在学习反射机制的时候,我们先来看下它的定义(到底是什么东西)。
反射的概念
主要是指程式可以访问、检测和修改他本身状态或行为的一种能力,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。
作为程序员我觉得下面的解释更好理解。
通过反射机制从Class对象中获取构造函数、成员变量、方法类等元素的反射对象。
反射机制中主要的反射类
Constructor:类的构造函数反射类
作用:可以通过getConstructor()方法获取类的所有构造函数反射对象数组。其中的一个方法newInstance(Obeject[] initargs)用来创建一个对象类的实例(New关键字)。
Method:类方法的反射类
作用:可以通过getDeclaredMethods()方法获取类的所有方法反射类对象数组。其中主要的方法是invoke(Object obj, Object[] args)用于调用需要的方法,参数obj则为需要操作的目标对象。
Field:类的成员变量的反射类
作用:可以通过getDeclaredFields()方法获取类的成员变量反射对象数组,通过getDeclaredFields(String name)方法则可获取指定成员变量的反射对象。其中有一个set(Object value)方法可以给操作的反射对象赋值。
实例
首先我们创建一个Dog类。
public class Dog {
//成员
private String name;
private int age;
private String breed;
//无参构造器
public Dog(){}
//带参构造器
public Dog(String name, int age, String breed){
this.name = name;
this.age = age;
this.breed = breed;
}
public void sprak(){
System.out.println("breed:"+breed+" name:"+name+" age:"+ age);
}
/*
* 成员的get/set方法 省略...
*/
}
一般我们在创建一个实例的时候,都是用new关键字来创建,例如下面代码创建Dog类的实例。
public static void main(String[] args) {
//第一种
Dog dog1= new Dog();
dog1.setName("阿黄");
//第二种
Dog dog2= new Dog("阿黄",3,"狗");
}
下面我们通过java反射机制来操作Dog类
public class ReflectDog {
public static Dog initByDefaultConst() throws Throwable{
//1.通过类装载器获取Dog对象
ClassLoader loader = Thread.currentThread().getContextClassLoader();
Class clazz = loader.loadClass("com.lzc.reflect.Dog");
//2.获取类的默认构造器对象并实例化Dog
Constructor cons = clazz.getDeclaredConstructor((Class[]) null);
Dog dog = (Dog)cons.newInstance();
//3.通过反射方法设置Dog的属性
Method setName = clazz.getMethod("setName", String.class);
setName.invoke(dog,"阿黄");
Method setAge = clazz.getMethod("setAge", int.class);
setAge.invoke(dog,3);
Method setBreed = clazz.getMethod("setBreed", String.class);
setBreed.invoke(dog,"土狗");
return dog;
}
public static void main(String[] args) throws Throwable {
Dog dog = initByDefaultConst();
dog.sprak();
}
}
输出结果:
breed:土狗 name:阿黄 age:3
下面是我简单画的一个图解,方便理解
结论
调用Class的各个功能来创建一个实例化类和通过构造函数和方法直接调用类功能来创建一个实例化的效果其实是一致的,只不过前者是间接调用,后者是直接调用。