反射机制:类属于动态加载的机制。
-
反射机制允许程序在执行期间借助Reflection ApI 取得任务类的内部信息(比如成员变量、构造器、成员方法),并能操作对象的属性和方法。反射设计模式和框架底层都会用到。
-
加载完类之后,在堆中就产生一个Class类型的对象(一个类只有一个Class对象),这个对象包含了类的完整结构信息。通过这个对象得到类的结构。这个Class类就像一面镜子,透过这个镜子看到这个类的结构,所以,形象的称之为"反射"。
一个类中能存在一个Class反射对象
java反射机制原理图:
反射中主要的类:
举个例子:
public class Cat {
//创建了一个属性:
public String name="招财喵";
//无参构造器
public Cat(){
}
//有参构造器:
public Cat(String name) {
this.name = name;
}
//创建了一个方法:
public void hi(){
System.out.println("hello 我是小哈" +name);
}
public void cry(){
System.out.println(name+"喵喵叫");
}
}
public class reflect_question {
public static void main(String[] args) throws IOException, ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
//使用properties读取配置文件;
Properties properties = new Properties();
properties.load(new FileInputStream("src\\re.properties"));
String classfullpath = properties.get("classfullpath").toString();
String method1 = properties.get("method1").toString();
String method2 = properties.get("method2").toString();
System.out.println("classfullpath:"+classfullpath);
System.out.println("method:"+method1);
//使用反射机制:Class是一个反射机制的类:
Class aClass = Class.forName(classfullpath);
//实例化类对象:newInstance()对象名;
Object o = aClass.newInstance();
System.out.println("运行类型是:"+o.getClass());
//使用反射类方法:
Method method01= aClass.getMethod(method1);
Method method02 = aClass.getMethod(method2);
//调用method.invoke
System.out.println("调用了method方法.invoke(对象名)");
method01.invoke(o);
System.out.println("====================================");
System.out.println("调用了method2.invoke(对象名)");
method02.invoke(o);
//使用反射机制中的属性:getField() 不能得到私有的属性:
Field nameFiled = aClass.getField("name");
//调用 成员变量.get(对象)
System.out.println("对象的name属性是:"+nameFiled.get(o));
//使用反射机制的无参构造器: 返回无参构造器:
Constructor constructor = aClass.getConstructor();
System.out.println(constructor);
//使用反射机制中的有参构造器:
Constructor constructor1 = aClass.getConstructor(String.class); //传入String来的Class对象;
System.out.println(constructor1);
}
}
配置文件:
classfullpath=com.hsp.Cat
method1=hi
method2=cry
Class类:
Class类常用的方法:
public class Car {
public String name="宝马";
public Double price=100000.0;
public String color="白色";
//无参构造器:
public Car(){
}
//有参构造器:
public Car(String name, Double price, String color) {
this.name = name;
this.price = price;
this.color = color;
}
@Override
public String toString() {
return "Car{" +
"name='" + name + '\'' +
", price=" + price +
", color='" + color + '\'' +
'}';
}
}
public class reflect_question03 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, InstantiationException {
//使用反射机制:
String classpath="com.hsp.Car";
Class<?> aClass = Class.forName(classpath);
//输出编译类型:
System.out.println("编译类型是:"+aClass);
//输出运行类型:
System.out.println("运行类型是:"+aClass.getClass());
//得到包名:
System.out.println("得到包名:"+aClass.getPackage().getName());
//得到全类名:
System.out.println("全类名:"+aClass.getName());
//实例化对象:
Car car = (Car) aClass.newInstance();
System.out.println("输出对象的toString方法:"+car);
//使用反射机制拿到name属性:
Field name = aClass.getField("name");
System.out.println("name属性是:"+name.get(car));
//使用反射机制设置属性:
name.set(car,"奔驰");
System.out.println("修改后的属性是:"+name.get(car));
//使用直接for循环遍历属性:
Field[] fields = aClass.getFields();
for (Field f: fields) {
System.out.println("得到属性名称:"+f.getName());
}
}
}
编译类型是:class com.hsp.Car
运行类型是:class java.lang.Class
得到包名:com.hsp
全类名:com.hsp.Car
输出对象的toString方法:Car{name='宝马', price=100000.0, color='白色'}
name属性是:宝马
修改后的属性是:奔驰
得到属性名称:name
得到属性名称:price
得到属性名称:color
类加载时机:
类的一些方法: