JAVA反射机制是在运行状态中,对于任意一个类(class文件)可以获取属性和方法。 动态获取类中信息,就是java的反射机制,可以理解为对类的解剖。
反射基础知识
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
public class TestReflect {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException {
//getClass
Person person =new Person();
Class class1 = person.getClass();
System.out.println(class1);
Person person2 =new Person();
Class class2 = person2.getClass();
System.out.println(class1==class2); //true
//.class
Class class3 = Person.class;
System.out.println(class1==class3); //true
//二维数据和一维数据类对象不同
int[] arr = new int[10];
int[] arr1 = new int[20];
int[][] brr = new int[10][10];
System.out.println(arr.getClass().hashCode()); //1232367853
System.out.println(arr1.getClass().hashCode()); //1232367853
System.out.println(brr.getClass().hashCode()); //328638398
//forName 可以放入配置文件
String className = "com.niliv.reflect.Person";
Class class4 = Class.forName(className);
System.out.println(class4==class1); //true
//早期 new时候,根据类名称找到字节码文件,加载进内存,并创建该字节码文件对象,并创建字节码文件对象的person对象
Person person3 = new Person(); //person run
//现在
String className1 = "com.niliv.reflect.Person";
//找到该名称字节码文件,加载进内存,产生Class字节码对象
Class class5 = Class.forName(className1);
System.out.println(class5.getName()); //com.niliv.reflect.Person
System.out.println(class5.getSimpleName()); //Person
System.out.println(class5.getSuperclass()); //class java.lang.Object
//创建class对象的person对象,也调用了空参构造函数,如果没有空参构造函数会报错
Object object = class5.newInstance(); //person run
//没有空参,可以通过指定的构造函数进行初始化 getConstructor
TestReflectField();
TestReflectMethod();
}
/**
* 获取类的属性
*/
public static void TestReflectField() throws NoSuchFieldException, SecurityException, NoSuchMethodException, ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
String className = "com.niliv.reflect.Person";
Class class1 = Class.forName(className);
//获取指定构造函数
Constructor constructor = class1.getConstructor(String.class,int.class,String.class,double.class,double.class);
Object object = constructor.newInstance("xiaoming",12,"cxy",12,12);
Field field = null;
// field = class1.getField("age"); //获取公共属性
// System.out.println("field"+field);
field = class1.getDeclaredField("age"); //只能拿本类,但可以是拿私有
System.out.println("field"+field); //fieldprivate int com.niliv.reflect.Person.age
// Field[] fields = class1.getFields(); //所有公有属性
// System.out.println("field"+fields);
Field[] fields2 = class1.getDeclaredFields();
for (Field field2 : fields2) {
System.out.println(field2);
}
//强制访问私有变量
field.setAccessible(true);
//操作属性的值
Object obj = class1.newInstance();
field.set(obj, 89);
System.out.println(field.get(obj)); //89
}
/**
* 获取方法
*/
public static void TestReflectMethod() throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
String className = "com.niliv.reflect.Person";
Class class1 = Class.forName(className);
//遍历本类所有方法
Method[] methods = class1.getDeclaredMethods();
for (Method method : methods) {
System.out.println(method.getName());
System.out.println(method.getReturnType());
System.out.println(method.getModifiers()); //权限
}
//获取方法
Method method = class1.getMethod("getName",null); //获取公有方法
Method method1 = class1.getMethod("setName",String.class); //有参
//操作方法
Constructor constructor = class1.getConstructor(String.class,int.class,String.class,double.class,double.class);
Object object = constructor.newInstance("xiaoming",12,"cxy",12,12);
method.invoke(object, null); //xiaoming
method1.invoke(object, "旺财");
method.invoke(object, null); //旺财
}
}
取消检查可以提高反射的效率 setAccessible(true);
public class ReflectDemo {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException {
test1(); //普通对象:323
test2(); //反射对象:4324
test3(); //反射对象取消检查:1054
}
private static void test1() {
Person person = new Person();
long startTime = System.currentTimeMillis();
for(int i =0;i<1000000000L;i++) {
person.getName();
}
long endTime = System.currentTimeMillis();
System.out.println("普通对象:"+(endTime-startTime));
}
private static void test2() throws ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException {
Class person = Class.forName("com.niliv.reflect.Person");
Method hs = person.getDeclaredMethod("getName", null);
long startTime = System.currentTimeMillis();
for(int i =0;i<1000000000L;i++) {
hs.invoke(person.newInstance(), null);
}
long endTime = System.currentTimeMillis();
System.out.println("反射对象:"+(endTime-startTime));
}
private static void test3() throws ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException {
Class person = Class.forName("com.niliv.reflect.Person");
Method hs = person.getDeclaredMethod("getName", null);
Person p = (Person)person.newInstance();
hs.setAccessible(true);
long startTime = System.currentTimeMillis();
for(int i =0;i<1000000000L;i++) {
hs.invoke(p, null);
}
long endTime = System.currentTimeMillis();
System.out.println("反射对象取消检查:"+(endTime-startTime));
}
}
public class User {
}
public class TestGeneric {
public void test01(Map<String,User> map,List<User> list,String s){
System.out.println("TestGeneric.test01()");
}
public Map<Integer,User> test02(){
System.out.println("TestGeneric.test02()");
return null;
}
public String test03(){
System.out.println("TestGeneric.test03()");
return null;
}
public static void main(String[] args) throws NoSuchMethodException, SecurityException {
//获取test01方法的泛型参数信息
Class c=TestGeneric.class;
Method test01=c.getMethod("test01", Map.class,List.class,String.class);
//获取带泛型参数的类型
Type [] tytes=test01.getGenericParameterTypes();
System.out.println(tytes.length);
for (Type type : tytes) {
//System.out.println("#"+type);
if (type instanceof ParameterizedType) {
Type[] genericType= ((ParameterizedType) type).getActualTypeArguments();
//遍历每一个泛型参数中泛型的类型
for (Type genType : genericType) {
System.out.println("泛型类型:"+genType);
}
System.out.println("\n--------------------------");
}
}
System.out.println("\n----------------------------\n");
//获取test02方法返回值的泛型信息
Method m2=c.getMethod("test02", null);
Type returnType=m2.getGenericReturnType();
//判断是否带有泛型
if(returnType instanceof ParameterizedType){
Type [] types=((ParameterizedType) returnType).getActualTypeArguments();
for (Type type : types) {
System.out.println("返回值的泛型类型:"+type);
}
}
System.out.println("\n------------------------------\n");
Method m3=c.getMethod("test03", null);
Type returnType3=m3.getGenericReturnType();
//System.out.println(returnType3);
System.out.println(returnType3 instanceof ParameterizedType);
}
}