JavaSE

反射-基本原理

2021-05-20  本文已影响0人  AIGame孑小白

反射概念和原理

如何理解反射?

在Java当中,任何一个类都包括:属性、方法和构造器

我们发现任何一个Java类都好像是约定好的一个模板,所谓万物皆对象,我们同样可以使用类来表示一个属性:

使用类表示属性:

class 属性{
    public String 修饰符;
    public String 类型;
    public String 属性名称;
    public String 属性值;
}

既然如此,同样的道理,我们也可以使用一个类分别表示方法和构造器,这样以来我们就使用了三个类分别表示了属性、方法和构造器,那么我们同样可以使用一个类来装载这三个类:

class 类{
    public 属性集合 属性s[];
    public 方法集合 方法s[];
    public 构造集合 构造s[];
}

到这里我们可以发现:我们可以使用一个类来表示任何类!这种思想便是反射(我讲的比较通俗哈,也不是特别专业)然而jdk早就想到了,于是为我们封装了一个名为Class的类。

三种获取Class对象的方式

1.Class.forName();/根据全限定路径获取
2.对象名称.getClass();//根据对象获取
3.类名.class//根据类名获取

第一种方式:创建类对象

Class clazz = Class.forName("Person");
Person person2 = (Person)clazz.newInstance();
person2.showInfo();

第二种方式:接收类对象

Class class1 = Person.class;

第三种方式:

Class class2 = new Person().getClass();

其实底层实现封装的类对象都是同一个

Class class1 = Class.forName("Person");
Class class2 = Person.class;
Class class3 = new Person().getClass();
System.out.println(class1==class2&&class2==class3);

操作属性

首先创建一个类

package 反射;

public class Person {
    public String name = "张三";
    public static int money = 100;
    private int age;
    private String sex;
    public Person() {}
    public Person(String name, int age, String sex) {
        super();
        this.name = name;
        this.age = age;
        this.sex = sex;
    }
    public void showInfo() {
        System.out.println("Person [name=" + name + ", age=" + age + ", sex=" + sex + "]");
    }
}

开始操作

//1.获取类对象
Class class1 = Class.forName("反射.Person");
//2.获取类属性
Field[] fileds = class1.getFields();
for (Field field : fileds) {
    //getName()会获取该类的公共字段和其父类的公共字段
    System.out.println(field.getName());
    //获取修饰符
    System.out.println(field.getModifiers());
    //获取类型:返回的是一个Class
    //注意:int的Class类型还是int
    System.out.println(field.getType());

}
System.out.println("-------------------------------");
//返回类声明的所有字段
Field fs2[] = class1.getDeclaredFields();
for (Field field : fs2) {
    System.out.println("修饰:"+field.getModifiers()+ "\t属性名:"+field.getName()+"\t类型:"+field.getType());
}
//获取父类的字段
//Field field = class1.getSuperclass().getDeclaredField("modif_name");
System.out.println("-------------------------------");

//获取静态属性
Field f3 = class1.getDeclaredField("money");
//操作静态属性
f3.set(null, 150);
System.out.println(f3.get(null));


//获取非静态变量
Field f4 = class1.getDeclaredField("name");
//赋值非静态属性
f4.set(class1.newInstance(), "李四");
System.out.println(f4.get(class1.newInstance()));

操作方法

随便创建的类

package 反射;

public class Fun {
    public void show(){
        System.out.println("我是一个方法");
    }
}

开始操作方法

Class clazz = Class.forName("反射.Fun");
//获取自身以及父类的所有方法
Method method1[] = clazz.getMethods();
for (Method method : method1) {
    System.out.println(method.getName());
}
System.out.println("-----------------------------");

//获取自身的方法
Method method2[] = clazz.getDeclaredMethods();
for (Method method : method2) {
    System.out.println(method.getName());
}

//调用show();没有形参就传入null
Method m1 = clazz.getDeclaredMethod("show", null);
//获取返回值类型void
System.out.println(m1.getReturnType());
m1.invoke(clazz.newInstance(), null);

常用方法整理

主要类

类名 解释
Class类 代表类的实体,在运行的Java应用程序中表示类和接口
Field类 代表类的成员变量(成员变量也称为类的属性)
Method类 代表类的方法
Constructor类 代表类的构造方法

Class类常用函数

方法 解释
asSubclass(Class clazz) 把传递的类的对象转换成代表其子类的对象
Cast 把对象转换成代表类或是接口的对象
getClassLoader() 获得类的加载器
getClasses() 返回一个数组,数组中包含该类中所有公共类和接口类的对象
getDeclaredClasses() 返回一个数组,数组中包含该类中所有类和接口类的对象
forName(String className) 根据类名返回类的对象
getName() 获得类的完整路径名字
newInstance() 创建类的实例
getPackage() 获得类的包
getSimpleName() 获得类的名字
getSuperclass() 获得当前类继承的父类的名字
getInterfaces() 获得当前类实现的类或是接口

获得类中属性相关的方法

方法 解释
getField(String name) 获得某个公有的属性对象
getFields() 获得所有公有的属性对象
getDeclaredField(String name) 获得某个属性对象
getDeclaredFields() 获得所有属性对象

获得类中注解相关的方法

方法 解释
getAnnotation(Class annotationClass) 返回该类中与参数类型匹配的公有注解对象
getAnnotations() 返回该类所有的公有注解对象
getDeclaredAnnotation(Class annotationClass) 返回该类中与参数类型匹配的所有注解对象
getDeclaredAnnotations() 返回该类所有的注解对象

获得类中方法相关的方法

方法 解释
getMethod(String name, Class…<?> parameterTypes) 获得该类某个公有的方法
getMethods() 获得该类所有公有的方法
getDeclaredMethod(String name, Class…<?> parameterTypes) 获得该类某个方法
getDeclaredMethods() 获得该类所有方法

Method类

方法 解释
invoke(Object obj, Object… args) 传递object对象及参数调用该对象对应的方法
上一篇 下一篇

猜你喜欢

热点阅读