JAVA反射机制
类对象
通俗的讲,类可以看做模板蓝图,是一个设计稿,类对象是一个做出来的模板,是一个模具,而对象就是用模具做出来的实例。
获取类对象有3种方式
- Class.forName();
- Hero.class;
- new Hero().getClass();
在一个JVM中,一种类,只会有一个类对象存在。所以以上三种方式取出来的类对象,都是一样的。
创建对象
// Son.java
// 注意三种方法里面的Son.class不会触发static代码块,其他两种会触发static,但是只有一次。
package demo;
public class Son{
static{
System.out.println("execution");
}
public Son(int i){
System.out.println("create"+i);
}
public Son() {
System.out.println("null");
}
void function(){
System.out.println("func");
}
}
// 使用类对象创建实例,注意getConstructor()方法只能获取public的的构造方法。
//getDeclaredConstructor()方法可以获取所有构造方法,getConstructor方法传递的参数是类对象如下所示:
Class sonClass = Son.class;
Constructor cons = sonClass.getConstructor(int.class); //这里声明是哪个构造函数,没有就不要写。
Son son = (Son)cons.newInstance(1); //在这里传参数,没有就不要写。
//记得使用try语句接异常。
访问属性
访问的属性只能是public的,对于private修饰的成员,需要使用field.setAccessible(true)才能访问和修改。
Field可以翻译成字段。
/*getField和getDeclaredField的区别:这两个方法都是用于获取字段,getField 只能获取public的,包括从父类继承来的字段。getDeclaredField 可以获取本类所有的字段,包括private的,但是不能获取继承来的字段。 (注: 这里只能获取到private的字段,但并不能访问该private字段的值,除非加上setAccessible(true))*/
//Son.java
public class Son{
private String name = "Ally";
}
//访问修改属性
Class sonClass = Son.class;
Constructor cons = sonClass.getConstructor();
Son son = (Son)cons.newInstance();
Field feild = sonClass.getDeclaredField("name");
feild.setAccessible(true); //需要这一句来获得权限。
feild.set(son,"XXX");
System.out.println(son.getName());
调用方法
同理和上面的使用方式类似
//Son.java
public class Son{
private void function(String str,int i){
System.out.println(str+i);
}
}
Class sonClass = Son.class;
Constructor cons = sonClass.getConstructor();
Son son = (Son)cons.newInstance();
Method method = sonClass.getDeclaredMethod("function",String.class,int.class);
method.setAccessible(true);
method.invoke(son,"XXX",5);//使用invoke调用,若是静态方法就使用Son.class
推荐一个方法:
在一个txt中写如下的的语句
name=XXX
value=YYY
可以通过以下方法获得键值对信息:
Properties springConfig= new Properties();
springConfig.load(new FileInputStream(springConfigFile));
String className = (String) springConfig.get("name");
String methodName = (String) springConfig.get("value");
这样就实现了使用txt来控制java代码
反射的使用
比如spring中的IOC依赖注入就经常使用这种方式,学习spring的时候就会碰到。