java反射机制
- 反射简介
- java代码在程序中经历的阶段
- 如何获取Class对象
- 如何获取成员变量
- 如何获取构造方法
- 如何获取成员方法
- 如何获类名
反射简介
1.反射是框架设计的灵魂
2.将类的各个组成部分封装为其他对象,这就是反射机制
3.反射的好处
**在程序的运行过程中,操作这些对象
可以解耦(降低耦合性,提高程序的可扩展性)
java代码在计算机中经历的阶段
源代码阶段:代码存在硬盘中,.class文件
Class类对象阶段:类加载器将.class从硬盘加载入内存中
RunTime运行时阶段:实例化对象进行操作
如何获取Class对象
第一阶段.Class.forName(“全类名”); 将字节码文件加载入内存,返回class
*多用于配置文件,将类名定义在配置文件中。读取文件,加载类
第二阶段.类名.class: 通过类名.class获取
*多用于参数的传递
第三阶段:对象.getclass 该方法在Object中
*多用于对象的获取字节码的方式
//1.Class.forName(“全类名”); 将字节码文件加载入内存,返回class
Class cls1 = Class.forName("com.lz.domain.Person");
System.out.println(cls1);
//2.类名.class: 通过类名.class获取
Class cls2=Person.class;
System.out.println(cls2);
//3:对象.getclass 该方法在Object中
Person mPerson=new Person();
Class cls3=mPerson.getClass();
System.out.println(cls3);
结论:同一个字节码文件(*.class)在一次程序的运行过程中,只会被加载一次,不论通过哪一种方式获取的Class对象都是同一个
如何获取成员变量
api的介绍和测试
*Field[] getFields():获取所有public修饰的成员变量
Field[] fields=mReflectPerson.getFields();
for (Field field : fields) {
System.out.println(field);
}
*Field[] getField(String name):获取指定名称由public修饰的成员变量、
Field mField1=mReflectPerson.getField("sex");
已经获取了成员变量:
1.设置值
mField1.set(mPerson,"female");
Object value1= mField1.get(mPerson);
System.out.println(value1);
2.获取值
Person mPerson=new Person();
Object value= mField1.get(mPerson);
System.out.println(value);
*Field[] getDeclaredFields():获取所有的成员变量,不考虑访问权限修饰符
Field[] fields=mReflectPerson.getDeclaredFields();
for (Field field : fields) {
System.out.println(field);
*Field[] getDeclaredField(String name):获取指定名称修饰的成员变量
Class<Person> mTest = Person.class;
try {
Person mTestPerson = new Person();
Field mTestField = mTest.getDeclaredField("name");
//非法的访问异常 需要忽略访问权限修饰符的安全检查
mTestField.setAccessible(true);//暴力反射
Object testDemo = mTestField.get(mTestPerson);
System.out.println(testDemo);
mTestField.set(mTestPerson, "张三");
Object testDemo1 = mTestField.get(mTestPerson);
System.out.println(testDemo1);
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}
如何获取构造方法
*Constructor<?>getConstructors()
*Constructor<T>getConstructor(类<?>...parameterTypes)
*Constructor<?>getDeclaredConstructors()
*Constructor<?>getDeclaredConstructor(类<?>...parameterTypes)
如何获取成员变量
*Method[] getMethods()
*Method[] getMethod(String name,类<?>...parameterTypes)
*Method[] getDeclaredMethods()
*Method[] getgetDeclaredMethod(String name,类<?>...parameterTypes)
如何获取类名
*Method[] getMethods()
*Method[] getMethod(String name,类<?>...parameterTypes)
*Method[] getDeclaredMethods()
*Method[] getgetDeclaredMethod(String name,类<?>...parameterTypes)
Field:成员变量
*操作:
1.设置值
*void set(Object obj,Object value)
2.获取值
*get(Object obj)
3.忽略访问权限的安全检查
*setAccessible(true):暴力反射
Person mTestPerson = new Person();
Field mTestField = mTest.getDeclaredField("name");
//非法的访问异常 需要忽略访问权限修饰符的安全检查
mTestField.setAccessible(true);//暴力反射
Object testDemo = mTestField.get(mTestPerson);
System.out.println(testDemo);
mTestField.set(mTestPerson, "张三");
Object testDemo1 = mTestField.get(mTestPerson);
System.out.println(testDemo1);
Constructor:构造方法
创建对象:
T newInstance(Object… initargs)
Constructor mConstructor=mReflectPerson.getConstructor(String.class,int.class);
System.out.println(mConstructor);
//使用构造器来创建对象
Object mPerson= mConstructor.newInstance("张三",23);
System.out.println(mPerson);
如果使用无参构造方法来创建对象,可以使用多种方法来创建
//调用空构造器的方法进行创建
Object mNullPerson=mReflectPerson.getConstructor();
System.out.println(mNullPerson);
//调用Class中的方法进行空参构造
Object mNullPerson2=mReflectPerson.newInstance();
System.out.println(mNullPerson2);
Method:执行方法
获得方法:getMethod(“方法名”,参数类型)
执行方法:invoke(“实例化对象”,参数表列)
/**
* getMethod:方法名 参数列表
* */
Method eat_method=mReflectPerson.getMethod("eat",String.class);
//进行参数的执行
eat_method.invoke(mPerson,"Lzinner");
获取类名
String className = mReflectPerson.getName();
System.out.println("类名为:"+className);
备注
上文中是对于反射的介绍,但是并没有给予所有的代码,详细的代码可以去github中进行参考
github:https://github.com/Lzin/java_code