反射

1、什么是反射

   反射是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,对于任意一个对象,都能够调用它的任意方法和属性,这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制

2、获取Class的三种方式
  第一种: Class.forName("类路径")
//第一种:根据student类的路径获取Student的反射类对象
Class<Student> aClass = (Class<Student>) Class.forName("FanSe1.Student");
System.out.println(aClass);

  第二种: 类名.class

//第二种:根据类的名获取Student类的反射对象
Class<Student> studentClass = Student.class;
Student student1 = studentClass.newInstance();
System.out.println("第二种:"+student1);

  第三种: 对象.getClass();

//第三种:通过类对象获取类的反射类对象
Student student = new Student();
Class aClass1 = student.getClass();

aClass == studentClass == aClass1 反射类相同

3、通过反射类获取类的对象

  通过Class类对象,调用newInstance()

//第一种:根据student类的路径获取Student的反射类对象
Class<Student> aClass = (Class<Student>) Class.forName("FanSe1.Student");
System.out.println(aClass);
//通过反射类得到对应的类对象---之前方式:new Student来获取Student类对象
Student aClassstudent = aClass.newInstance();
System.out.println("第一种:"+aClassstudent);

 4 获取反射类中的属性成员对象

  字节码中的属性成员被加载到内存中后会以Field类对象的形式存在。如何获取Field属性对象。

  类:

class Student2{
    private String name;
    private Integer age;
    public String hopp;
    Integer qqq;

    public String getHopp() {
        return hopp;
    }

    public void setHopp(String hopp) {
        this.hopp = hopp;
    }

    public Integer getQqq() {
        return qqq;
    }

    public void setQqq(Integer qqq) {
        this.qqq = qqq;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
    public void show(){
        System.out.println("名字:"+name);
        System.out.println("年龄:"+age);
    }

    @Override
    public String toString() {
        return "Student2{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", hopp='" + hopp + '\'' +
                ", qqq=" + qqq +
                '}';
    }

  · getDeclaredFields() --查询类中所有的类对象

//1、获取Student2类的反射类
Student2 student2 = new Student2();
Class aClass2 = student2.getClass();
//获取反射类中的成员对象 --获取本类中所有的属性对象
Field[] declaredFields = aClass2.getDeclaredFields();
for (Field field : declaredFields) {
    System.out.println("==="+field);
}

   ·getDeclaredField --通过类的名字获取类对象

//1、获取Student2类的反射类
Student2 student2 = new Student2();
Class aClass2 = student2.getClass();
//通过类的名字获取参数
Field declaredField = aClass2.getDeclaredField("name");
System.out.println("----"+declaredField);

   ·getFields()   --获取本类以及父类中public属性对象

//1、获取Student2类的反射类
 Student2 student2 = new Student2();
Class aClass2 = student2.getClass();
//获取本类以及父类中public属性对象
Field[] fields = aClass2.getFields();
for (Field field : fields) {
    System.out.println("-=-="+field);
}

   ·getField()  --指定名称的公共字段的对象

//1、获取Student2类的反射类
Student2 student2 = new Student2();
Class aClass2 = student2.getClass();
//指定名称的公共字段的对象
Field name = aClass2.getField("hopp");
System.out.println("+_+"+name);

5、Field类中具有的常用方法

  · setAccessible(true): 设置允许访问私有属性

  · getAnnotation(注解.class):获取属性上的注解对象

//1、获取反射类对象
Class<Student3> student3Class = Student3.class;
//2、通过反射类得到类对象
Student3 student3 = student3Class.newInstance();
System.out.println(student3);
//3、得到反射类中的age属性对象
Field age = student3Class.getDeclaredField("age");
//通过age属性对象为Student对象赋值
age.set(student3,18);
System.out.println(student3);
//4、获取私有的反射类中的name属性对象
Field name = student3Class.getDeclaredField("name");
//允许私有的属性赋值
name.setAccessible(true);
name.set(student3,"张三");
System.out.println(student3);

 

class Student3{
    private String name;
    public Integer age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
    public void show(){
        System.out.println("名字:"+name);
        System.out.println("年龄:"+age);
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

 

 6、获取方法类对象

方法类对象:

class ZhangSan{
    public void fun1(){
        System.out.println("-----");
    }
    public String fun2(int age){
        System.out.println("===="+age);
        return "fun2";
    }
    private String fun3(String name){
        return "fun3"+name;
    }
    private String fun4(){
        return "fun4";
    }

   ·getDeclaredMethods()  --查询类中所有的方法类对象

Class<ZhangSan> zhangSanClass = ZhangSan.class;
ZhangSan zhangSan = zhangSanClass.newInstance();
//获取本类中所有的Method方法对象
Method[] declaredMethods = zhangSanClass.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
    System.out.println("Method方法对象:"+declaredMethod);
}

   ·getMethods()   --获取本类以及父类中public修饰的方法对

Class<ZhangSan> zhangSanClass = ZhangSan.class;
ZhangSan zhangSan = zhangSanClass.newInstance();
//获取本类以及父类中public修饰的方法对象
Method[] methods = zhangSanClass.getMethods();
for (Method method : methods) {
    System.out.println("获取公共方法类:"+method);
}

   ·getMethod("类名",类型.class)  --查询类中公共public指定的方法对象

Class<ZhangSan> zhangSanClass = ZhangSan.class;
ZhangSan zhangSan = zhangSanClass.newInstance();
//查询类中指定的方法对象
Method method = zhangSanClass.getMethod("fun2",int.class);
System.out.println("+++"+method);

 7、Method类中常用的方法

    · invoke(): 执行该方法体。

     Class<ZhangSan1> zhangSan1Class = ZhangSan1.class;
        ZhangSan1 zhangSan1 = zhangSan1Class.newInstance();
        Method fun3 = zhangSan1Class.getMethod("fun3", int.class, String.class);
        //回调该方法   执行该方法
        Object zs = fun3.invoke(zhangSan1, 16, "张三");
        System.out.println(zs);
class ZhangSan1{
    public String fun3(int age,String name){
        System.out.println(age);
        System.out.println(name);
        return "fun3";
    }
}

    · getAnnotation()  --返回该元素的指定类型的注释,否则返回null

BH annotation = fun3.getAnnotation(BH.class);
System.out.println(annotation.value());
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interface BH{
    String value();
}
class ZhangSan1{
    @BH("今日复明日,明日何其多")
    public String fun3(int age,String name){
        System.out.println(age);
        System.out.println(name);
        return "fun3";
    }
}

 8、获取构造对象

构造函数:

class A {
    public A() {
        System.out.println("父类的无参构造函数");
    }

    public A(String name) {
        System.out.println("这是父类的有参构造函数:" + name);
    }
}
   class B extends A{
       public B(){
           System.out.println("子类的无参");
       }
       public B(String name){
           System.out.println("子类的有参:"+name);
       }
       public B(Integer age){
           System.out.println("有参私有构造");
       }
   }

   ·getDeclaredConstructors()  --获得所有的访问权限的构造函数

Class<?> aClass = Class.forName("FanSe1.B");
//得到类对象 -- 调用构造函数
Object o = aClass.newInstance();
Constructor<?>[] declaredConstructors = aClass.getDeclaredConstructors();
for (Constructor<?> declaredConstructor : declaredConstructors) {
    System.out.println(declaredConstructor);
}

   ·getConstructors  --只能获得public修饰的构造函数

Constructor<?>[] constructors = aClass.getConstructors();
for (Constructor<?> constructor : constructors) {
    System.out.println(constructor);
}

 9、Constructor类中常用的方法

构造函数:

class A {
    public A() {
        System.out.println("父类的无参构造函数");
    }

    public A(String name) {
        System.out.println("这是父类的有参构造函数:" + name);
    }
}
   class B extends A{
       public B(){
           System.out.println("子类的无参");
       }
       public B(String name){
           System.out.println("子类的有参:"+name);
       }
       private B(Integer age,String name){
           System.out.println("有参私有构造age:"+age+"有参私有构造name:"+name);
       }
   }

   ·getDeclaredConstructor(属性.class,.....)  --用于获取某个类的指定构造方法,返回一个Constructor对象,表示指定的构造方法

Constructor<?> declaredConstructor1 = aClass.getDeclaredConstructor(Integer.class,String.class);
declaredConstructor1.setAccessible(true);
Object helloWorid = declaredConstructor1.newInstance(18,"hello worid");

 

 

 

posted @ 2023-08-11 09:09  PHOEDE  阅读(63)  评论(0)    收藏  举报