一、什么是反射机制
JAVA反射机制是在运行状态中,对于任意一个实体类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性。
通过反射获取类对象的四种方式
//方法一
//创建一个对象
test1 ts=new test1();
//获取该对象的Class对象
Class c=ts.getClass();
//获取类名称
System.out.println(c.getName());//javaFanse.test1
//方法2
Class c=test1.class;
//获取类名称
System.out.println(c.getName());//javaFanse.test1
//方法三
try {
//根据类的全路径名获取
Class c=Class.forName("javaFanse.test1");
//获取类名称
System.out.println(c.getName());//javaFanse.test1
} catch (ClassNotFoundException e) {
// TODO: handle exception
e.printStackTrace();
}
*注:第一种已经创建了对象,那么这个时候就不需要去进行反射了,显得有点多此一举。
第二种需要导入类的包,依赖性太强
三、反射的应用
1、通过反射获取类的构造方法
Class c=Class.forName("javaFanse.test1");
//获取所有公用的构造方法
Constructor[] constructor=c.getConstructors();
for (Constructor constructor2 :constructor) {
System.out.println(constructor2);
}
//获取所有的构造方法
Constructor[] declaredConstructors=c.getDeclaredConstructors();
for (Constructor constructor2 : declaredConstructors) {
System.out.println(constructor2);
}
//获取无参的构造方法
Constructor constructor2=c.getConstructor(null);
System.out.println(constructor2);
//获取公有的有参的构造方法
Constructor con1=c.getConstructor(new Class[]{String.class,Integer.class,String.class});
System.out.println(con1);
//获取私有的有参的构造方法
Constructor con2=c.getDeclaredConstructor(new Class[]{String.class});
System.out.println(con2);
2.获取类的方法
//获取Class对象
Class c3=Class.forName("javaFanse.test1");
System.err.println("=============获取所有的public修饰的方法==============");
Method[] me1=c3.getMethods();
for (Method method : me1) {
System.out.println(me1);
}
Thread.sleep(1000);
System.err.println("=============获取所有方法===============");
Method[] me2=c3.getDeclaredMethods();
for (Method method : me2) {
System.out.println(me2);
}
Thread.sleep(1000);
System.err.println("==============获取特定方法(带参)并使用===========");
Method me3=c3.getMethod("method1",String.class);
System.out.println(me3);
Thread.sleep(1000);
System.err.println("==============获取特定方法(不带参)并使用==========");
Method me4=c3.getDeclaredMethod("method2");
System.out.println(me4);
Thread.sleep(1000);
System.err.println("==============获取特定方法(多个参数)并使用=========");
Method me5=c3.getDeclaredMethod("method3",String.class,Integer.class,String.class);
//获取构造方法,实例化对象
Object obj=c3.getConstructor().newInstance();
//给方法传值
Object obj2=me5.invoke(obj,"小涛",24,"男");
System.out.println(obj2);
3.获取类的属性
//获取Class对象
Class c2=Class.forName("javaFanse.test1");
System.out.println("==========获取所有的公共字段===========");
Field[] field1=c2.getFields();
for (Field field : field1) {
System.out.println(field);
}
System.out.println("==========获取所有的字段===========");
Field[] declarField=c2.getDeclaredFields();
for (Field field : declarField) {
System.out.println(field);
}
System.out.println("==========获取公有的字段并使用===========");
//获取指定公有字段
Field field3=c2.getField("name");
//获取一个公有构造方法,然后实例化
Object obj=c2.getConstructor().newInstance();
//为属性设置值
field3.set(obj, "张三");
//测试,看设置的值是否成功
test1 ts=(test1)obj;
System.out.println(ts.getName());
System.out.println("==========获取私有的字段并使用===========");
Field field4=c2.getDeclaredField("sex");
//获取构造函数实例化对象
Object obj1=c2.getDeclaredConstructor().newInstance();
//暴力反射
field4.setAccessible(true);
//给属性设置值
test1 t=(test1) obj1;
System.out.println(t.getSex());
注:获取私有属性的时候要进行暴力反射
总结:
反射最重要的用途就是开发各种通用框架。比如很多框架(Spring)都是配置化的(比如通过XML文件配置Bean),为了保证框架的通用性,它们可能需要根据配置文件加载不同的类或者对象,调用不同的方法,这个时候就必须使用到反射了,运行时动态加载需要的加载的对象。