反射可以把类的一些属性,普通方法,构造方法单取出来封装成一个类放在在Class类里面
准备一个Dome1类方便测试
package 反射;
import java.lang.reflect.Field;
public class Dome1 {
public String name;
public Integer age;
private String number;
public Dome1() {
}
public Dome1(String name, Integer age, String number) {
super();
this.name = name;
this.age = age;
this.number = number;
}
@Override
public String toString() {
return "Dome1 [name=" + name + ", age=" + age + ", number=" + number + "]";
}
public void eat() {
System.out.println("eat....");
}
public void eat(String food) {
System.out.println("eat....."+food);
}
}
一`、class类的获取
-----Class的静态方法forName(String)一般于配置文件连用
//1还未加载内存时,利用Class.forName(全类名)的方式将.class文件加载进入类存获得Class的对象 Class cls1 = Class.forName("反射.Dome1"); System.out.println(cls1);
-----类名.class
//2如果已经进入内存,可以用类名.Class的方式进入内存 Class cls2 = Dome1.class; System.out.println(cls2);
-----对象.class
//3通过对象名.getClass的方式获得Class类 反射.Dome1 dome = new Dome1("小红", 17, "123456"); Class cls3 = dome.getClass();
二 通过Class类获取属性,方法,构造函数
1.获取属性类 Field
-----getFields() ,getField(String) 只可以获取private修饰的属性
Class<Dome1> Dome1Class = Dome1.class; Field[] Dome1Fields = Dome1Class.getFields(); for (Field Dome1Field : Dome1Fields) { System.out.println(Dome1Field); } Field field = Dome1Class.getField("name"); System.out.println(field);
-----getDeclareFields() getDeclareField(Stirng) 可以忽略属性的限制获取任何属性
Field[] declaredFields = Dome1Class.getDeclaredFields();
for (Field declaredFields2 : declaredFields) {
System.out.println(declaredFields2);
}
Field declaredField = Dome1Class.getDeclaredField("number");
System.out.println(declaredField);
-----通过 set(Object, value) 和 get(Object)方法可以设置和获取而属性
/*
获取后可设置属性和获得属性的值
使用 get(Objec) set(Object, value)
*/
//构造一个person对象测试这两个方法
反射.Dome1 person = new Dome1("小明", 18, "123456");
//之前获得的关于name的Field对象
Object name = field.get(person);
System.out.println(name);
field.set(person,"小红");
System.out.println(person.name);
//之前获得的关于number的declaredField对象
//需要设置setAccessible()才可以访问private修饰的属性
declaredField.setAccessible(ture);//又称暴力反射
Object number = declaredField.get(person);
System.out.println(number);
declaredField.set(person,"456789");
number = declaredField.get(person);
System.out.println(number);
2.获取构造方法的类
下面以不含declared的为例
-----getConstructor(String,value...) (getConstructors()可以获得所有的构造方法以数组保存)
//获得有参构造方法
Constructor<反射.Dome1> constructor = Dome1.class.getConstructor(String.class, Integer.class, String.class);
//通过Method的newInstance方法对其初始化
反射.Dome1 newInstance = constructor.newInstance("小明", 18, "123456");
System.out.println(newInstance);
//获得无参构造方法
Constructor<反射.Dome1> constructor = Dome1.class.getConstructor();
//通过Method的newInstance方法对其初始化
反射.Dome1 newInstance = constructor.newInstance();
System.out.println(newInstance);
3获得普通方法的类
下面以不含declared的为列
-----getMethod(String,value...) (getMethods()可以获得所有的构造方法以数组保存)
//无参构造方法 //Class 类的getMenthod(方法名,参数...) 使用Methond 类的getName方法可以获得方法名 Method method = Dome1.class.getMethod("eat"); String methodName = method.getName(); System.out.println(methodName); //有参构造方法 Method method2 = Dome1.class.getMethod("eat", String.class); String Method2Name = method2.getName(); System.out.println(Method2Name); //使用方法 反射.Dome1 person = new Dome1("小明", 18, "123456"); method.invoke(person); method2.invoke(person, "肉"); //获得所有的类方法(除了本身写的eat方法外还有继承自Oject的方法) Method[] methods = Dome1.class.getMethods(); for (Method methods2 : methods) { System.out.println(methods2.getName()); }
4 获得类名
/* 获得类名 */ String className = Dome1.class.getName(); System.out.println(className);
三 反射的运用——框架
通过配置文件加反射的形式,使得每次创建什么样的对象使用什么样的放法可以通过修改配置文件的方式来修改,而不需要修改代码
先在src路径下加入pro.properties文件
Properties pro = new Properties(); //通过类加载器获得配置文件的io流 ClassLoader classLoader = Dome3.class.getClassLoader(); InputStream is = classLoader.getResourceAsStream("pro.properties"); //通过Properties类获得类的信息 pro.load(is); String property1 = pro.getProperty("className"); String property2 = pro.getProperty("classMethod"); System.out.println(property1); System.out.println(property2); //运用反射创获得Dome1的Class类并且创建一个obj对象 Class dome1= Class.forName(property1); Constructor constructor = dome1.getConstructor(String.class, Integer.class, String.class); Object obj = constructor.newInstance("小明", 18, "123456"); //使用方法 Method eatMethod = dome1.getMethod("eat"); eatMethod.invoke(obj);