反射

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);
	}
	
}

书籍推荐