2.2 反射机制
- Java反射机制提供的功能
- 在运行时判断任意一个对象所属的类
- 在运行时构造任意一个类的对象
- 在运行时判断任意一个类所具有的成员变量和成员方法
- 在运行时获取泛型信息
- 在运行时调用任意一个对象的成员变量和成员方法
- 在运行时处理注解
- 生成动态代理
- ......
- 反射机制的优缺点:
- 优点:可以实现动态创建对象和编译,体现出相当大的灵活性
- 缺点:对性能有影响。使用反射基本上是一种解释操作,我们可以告诉JVM,我们希望它做什么并且它能够满足我们的要求。这类操作总是慢于直接执行相同的操作(基于这个原因,在没有什么特殊情况时,不得使用反射)
- 反射的API:
- java.lang.Class : 代表一个类
- java.lang.reflect.Method : 代表类的方法
- java.lang.reflect Field : 代表类的成员变量
- java.lang.reflect.Constructure : 代表类的构造器
- ......
package refection ; import java.util.Objects; // 反射 public class Test { @SuppressWarnings("all") public static void main(String[] args) throws ClassNotFoundException { // 创建对象,实际上时需要泛型的,但是没有,用不到,直接去掉。 看着难受就强行镇压黄色的提示 Class c1 = Class.forName("refection.User"); // 一个类在内存中只有一个Class对象,可以进行验证 // 验证的方式:多次获取,看哈希码是否相同 // 一个类被加载之后,类的整个结构都会被封装在Class对象中 Class c2 = Class.forName("refection.User"); Class c3 = Class.forName("refection.User"); Class c4 = Class.forName("refection.User"); System.out.println(c2.hashCode()); System.out.println(c3.hashCode()); System.out.println(c4.hashCode()); } } // 实体类:pojo、entity类 class User{ private String name ; private int id ; private int age ; public User() { } public User(String name, int id, int age) { this.name = name; this.id = id; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "User{" + "name='" + name + ''' + ", id=" + id + ", age=" + age + '}'; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; User user = (User) o; return id == user.id && age == user.age && Objects.equals(name, user.name); } @Override public int hashCode() { return Objects.hash(name, id, age); } }
2.3 获得class对象的几种方式
- 获取class对象的方式一共有三种:
- 方式一:通过对象获得
- 方式二:通过反射forName获得
- 方式三:通过类名.class获得
- 方式四:通过内置的基本数据类型的包装类
- 方式五:通过ClassLoader(后面讲解)
package refection ; import java.util.Objects; public class Test02 { @SuppressWarnings("all") public static void main(String[] args) throws ClassNotFoundException { Person person = new Student(); System.out.println("这个人是" + person.name); // - 方式一:通过对象获得 Class c1 = person.getClass(); System.out.println(c1.hashCode()); // - 方式二:通过反射forName获得 Class c2 = Class.forName("refection.Student"); System.out.println(c2.hashCode()); // - 方式三:通过类名.class获得 Class c3 = Student.class ; System.out.println(c3.hashCode()); // 方式四:通过内置类型的包装类都有一个Type属性 Class c4 = Integer.TYPE ; System.out.println(c4); System.out.println(c4.hashCode()); // 获取父类型 Class c5 = c1.getSuperclass(); System.out.println(c5); } } class Person { public String name ; public Person (){ } public Person(String name){ this.name = name ; } @Override public String toString() { return "Person{" + "name='" + name + ''' + '}'; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Person person = (Person) o; return Objects.equals(name, person.name); } @Override public int hashCode() { return Objects.hash(name); } } class Student extends Person{ public Student(){ this.name = "学生" ; } } class Teacher extends Person{ public Teacher(){ this.name = "教师" ; } }