Java反射技术笔记

说明点:
1#Java中java.lang.Class类用于表示一个类的字节码(.class)文件
2#得到这个class文件对应的class对象,在未知类和对象的情况下,使用Class.forName(“包名.类名”)
3#forName用于加再类字节码到内存中,并封装成一个Class对象
4#Class对象是一个特殊的对象,是用来创建其它对象的对象(这里的其他对象就是指:java类的实例)。其实Class对象就是java类编译后生成的.class文件,它包含了与类有关的信息。每当第一次使用一个类时,JVM必须使用“类加载器”子系统加载该类对象的Class对象。一旦这个类的Class对象被载入内存,它就被用来创建这个类的所有对象。

Constructor类
1#Constructor类的实例对象代表类的一个构造方法
2#得到某个类所有的构造方法
Constructor[] constructor = Class.forName(“java.lang.String”).getConstructors();
3#得到指定的构造方法并调用
Constructor constructor = Class.forName(“java.lang.String”).getConstructors(String class);
String str = (String)constructor.newInstance(“abc”);
4#Class类的newInstance()方法用来调用类的默认构造方法
String obj = (String)Class.forName(“java.lang.String”).newInstance();

//获得无参数的构造方法
public void test1() throws Exception {
    Class class1 = Class.forName("Student");
    Constructor c = class1.getConstructor();
    Student student = (Student) c.newInstance();
}
//获得有参数的构造方法
public void test2() throws Exception {
    Class class1 = Class.forName("Student");
    Constructor c = class1.getConstructor(String.class,Integer.class);
    Student student = (Student) c.newInstance("Jessica",30);
}
//书本例子(&&&)
public Student getInstance() throws Exception {
    Student object = null;
    object = (Student)Class.forName("Student").getConstructor(String.class,Integer.class).newInstance("Derrick",21);
    return object    
}

File类代表某个类中的一个成员变量(注意是一个),并提供动态的访问权限
1#获取到字节码文件之后,通过以下语句获得成员变量

Field[] fields = c.getFields();    //取得所有public属性
Field[] fields = c.getDeclaredFields();   //取得所有声明的属性

2#通过以下语句获得指定的成员变量

Field name = c.getField("name");
Field name = c.getDeclaredField("name");   //比较常用,不管是公有属性还是私有属性

3#设置Field变量是否可以访问

filed.setAccessible(boolean);

4#Field变量值的读取、设置

field.get(obj);
field.set(obj,value);
//测试私有的属性(公有的直接.便可以使用)
public void test3() throws Exception{
    //获得class字节码
    Class class1 = Class.forName("Student");
    //获得私有属性
    Field field = class1.getDeclaredField("name");
    //操作属性
    Student student =(Student) class1.newInstance();
    //私有属性,设置一个可以访问的权限
    field.setAccessible(true);
    field.set(student,"Jessica"); //相当于student.name="Jessica"
    //获取值(返回的是object类型)
    Object obj = field.get(student);
}

Method类代表某个类中的一个成员方法
1#获取所有方法
getDeclaredMethods()
getMethods()
2#获取指定的方法(方法名称,参数列表)
getDeclaredMethods(String name,Class<?>…parameter Types)
getMethod(String name,Class<?>…parameter Types)
3#通过反射执行方法(类,具体的参数)
invoke(Object obj,Object…args)

//测试公有方法
public void test4() throws Exception{
    Class class1 = Class.forName("Student");
    //实例化
    Student student = (Student)class1.newInstance();
    //获得公有的方法
    Method method = class1.getMethod("Test");
    //执行该方法
    method.invoke(student);   //相当于student.test();
}
//测试私有方法
public void test5() throws Exception{
    Class class1 = Class.forName("Student");
    //实例化
    Student student = (Student)class1.newInstance();
    //获得方法
    Method method = class1.getDeclaredMethod("Test");
    //设置私有属性的访问权限
    method.setAccessible(true);
    //执行该方法
    method.invoke(student,null);
}
//测试私有的方法带参数与返回值
public void test6() throws Exception{
    Class class1 = Class.forName("Student");
    //实例化
    Student student = (Student)class1.newInstance();
    //获得方法
    Method method = class1.getDeclaredMethod("Test",String.class);
    //设置访问权限
    method.setAccessible(true);
    //执行,如果有返回值,则为object类型,如果自己知道类型可以进行强转
    Object obj = method.invoke(student,"Jessica");
}
//课本例子
public void test7() throws Exception{
    Student object = null;
    object = (Student)Class.forName("Student").newInstance();
    Method method = object.getClass().getMethod("sayHello",String.class);
    method.invoke(object,"Jessica");
}

&&对象在反射机制下生成后,反射了方法,这样我们完全可以通过配置来完成对象和方法的反射。

猜你喜欢

转载自blog.csdn.net/weixin_43912883/article/details/86382728