Class 类:类的实例表示正在运行的 Java 应用程序中的类和接口。枚举是一种类,注释是一种接口。每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。一个Class对象表示表示的是一种类型,但这个类型未必是一种类,比如int.class是一个Class对象,而int不是类。
Field 类:提供有关类或接口的属性的信息,以及对它的动态访问权限。反射的字段可能是一个类(静态)属性或实例属性,简单的理解可以把它看成一个封装反射类的属性的类。
Constructor 类:提供关于类的单个构造方法的信息以及对它的访问权限。这个类和 Field 类不同,Field 类封装了反射类的属性,而 Constructor 类则封装了反射类的构造方法。
Method 类:提供关于类或接口上单独某个方法的信息。所反映的方法可能是类方法或实例方法。这个类不难理解,它是用来封装反射类方法的一个类。
如何获得字节码?
Class cls = Xxx.class;
Class cls = xx.getClass();
Class.forname(类名); // 返回字节码:若内存中有加载该类,则他找到该类的字节码并返回,若无,则找到该类的路径,加载后返回。
要区别一个概念,这里获得的是类的字节码,与具体的对象无关。
如何获得实例?
Test t1=new Test();
Object t2 =t1.getClass().newInstance();
Object t3 =Class.forName("Test").newInstance();
newInstance方法调用没有参数的构造器,如果带参数就需要使用Constructor类。
Class类中的getFields、getMethods、getConstructors将返回类支持的public域、方法、和构造器数组,包括超类的公有成员。
Class类中的getDeclareFields、getDeclareMethods、getDeclareConstructors将返回类中声明的全部域、方法、和构造器数组,其中包括私有的和保护的,但不包括超类的成员。
Field、Method、Constructor都有一个getModifiers方法,可以使用其枚举值判断修饰符,或者Modifier.toString方法等解析。
AccessibleObjecte是Field、Method、Constructor公共超类,调用setAccessible(true)方法后可以对实例的保护和私有成员设置新值。这个特性是为调试、持久存储相似机制提供的。
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import javax.accessibility.AccessibleRole;
public class ReflectTest {
public static int a = 47;
private String str = "hello";
public ReflectTest() {
}
public ReflectTest(String str) {
this.str = str;
}
public String getStr(String str) {
return this.str + "," + str;
}
public String getStr() {
return str;
}
public static void MethodTest(Object object) {
};
public static void main(String[] args) throws Exception {
ReflectTest instance = new ReflectTest();
// 获取字节码
Class clazz = Class.forName("ReflectTest");
// 获取字段信息
Field fieldA = clazz.getField("a");
fieldA.getName();
fieldA.getType();
Modifier.toString(fieldA.getModifiers());
fieldA.getInt(instance);
fieldA.get(instance);
//设置私有成员
Field fieldStr = clazz.getDeclaredField("str");
fieldStr.setAccessible(true);
// AccessibleObject.setAccessible(array, flag)
fieldStr.set(instance, "abc");
// 根据字节码构造实例
Constructor<ReflectTest> constructor = clazz.getConstructor();
instance = constructor.newInstance();// 无参
instance = (ReflectTest) clazz.newInstance(); // 无参
constructor = clazz.getConstructor(String.class);// 有参
instance = constructor.newInstance("world");
// 调用指针函数
Method method1 = instance.getClass().getMethod("getStr");
method1.invoke(instance);//无参
method1 = instance.getClass().getMethod("getStr", String.class);
method1.invoke(instance, "String str");// 有参
method1 = instance.getClass().getMethod("MethodTest", Object.class);
method1.invoke(null, "object");// 静态
}
// 使用反射编写通用的数组代码
static Object GoodArryGrow(Object src) {
Class cl = src.getClass();
if (!cl.isArray())
return null;
Class componentType = cl.getComponentType();
int length = Array.getLength(src);
int newLength = length * 11 / 10 + 10;
Object dest = Array.newInstance(componentType, newLength);
System.arraycopy(src, 0, dest, 0, newLength);
return dest;
}
}