Java注解与反射(三)

135 阅读3分钟

这是我参与11月更文挑战的第20天,活动详情查看:2021最后一次更文挑战

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 = "教师" ;
     }
 ​
 }