概念
- 反射机制是在
运行状态中:
 对于任意一个类,都能够知道这个类的所有属性和方法。
 对于任意一个对象,都能够调用它的任意一个方法和属性。 
提供的功能
- 在运行时判断任意一个对象所属的类
 
- 在运行时构造任意一个类的对象
 
- 在运行时判断任意一个类所具有的的成员变量和方法
 
- 在运行时调用任意一个对象的方法
 
- 生成动态代理
 
获得反射入口的三种方式(获得类)
Class.forName(全类名)(推荐使用)
1 2 3 4 5 6
   | try { 		Class<?> classStu = Class.forName("reflect.Student"); 		System.out.println(classStu); 	} catch (ClassNotFoundException e) { 		e.printStackTrace(); 	}
  | 
 
类名.class
1 2
   | Class<?> classStu2 = Student.class; System.out.println(classStu2);
   | 
 
对象.getClass()
1 2 3
   | Student stu = new Student(); Class<?> classStu3 = stu.getClass(); System.out.println(classStu3);
   | 
 
通过反射获取类的相关信息
获取所有的公共的方法
- 方法范围是本类以及父类、接口中的所有公有的方法
 
- 符合访问修饰的规律
 
1 2 3 4
   | Method[] methods = classStu.getMethods();     		for(Method method : methods) {     			System.out.println(method);     		}
   | 
 
获取该类的所有接口
1 2 3 4
   | Class<?>[] interfaces = classStu.getInterfaces(); 		for(Class<?> inter : interfaces) { 			System.out.println(inter); 		}
   | 
 
获取该类的父类
1 2
   | Class<?> superClass = classStu.getSuperclass(); 		System.out.println(superClass);
   | 
 
获取该类的所有的构造方法
1 2 3 4
   | Constructor<?>[] constructors = classStu.getConstructors(); 		for (Constructor constructor : constructors) { 			System.out.println(constructor); 		}
   | 
 
获取所有公共属性
1 2 3 4
   | Field[] fields = classStu.getFields(); 		for (Field field : fields) { 			System.out.println(field); 		}
   | 
 
获取当前类的所有方法
- 包含私有方法(忽略访问修饰符)
 
- 不包括父类方法,但包含接口的实现方法
 
1 2 3 4
   | Method[] declaredMethods = classStu.getDeclaredMethods(); 		for (Method declaredMethod : declaredMethods) { 			System.out.println(declaredMethod); 		}
   | 
 
获取当前类的所有属性
1 2 3 4
   | Field[] declaredFields = classStu.getDeclaredFields(); 		for (Field declaredField : declaredFields) { 			System.out.println(declaredField); 		}
   | 
 
获取当前反射所代表类(接口)的对象(实例)
1 2 3
   | Object newInstance = classStu.newInstance(); 		Student stu = (Student)newInstance; 		stu.breathe();
   | 
 
通过反射获取对象的实例,并操作对象(实例)
操作属性
1 2 3 4 5
   | Student stu = (Student)classStu.newInstance(); 		Field idFieAge = classStu.getDeclaredField("age"); 		idFieAge.setAccessible(true);//修改访问权限(private) 		idFieAge.set(stu, 1);//相当于stu.setAge(1); 		System.out.println(stu.getAge());
   | 
 
操作函数
1 2 3 4
   | Student stu = (Student)classStu.newInstance(); 		Method method = classStu.getDeclaredMethod("sleep", null);//(函数名,参数) 		method.setAccessible(true);//private函数 		method.invoke(stu, null);//null表示无参数
   | 
 
1 2 3
   | Student stu = (Student)classStu.newInstance(); 		Method method = classStu.getDeclaredMethod("habby", String.class);//参数类型 		method.invoke(stu, "篮球");
   | 
 
注:在反射中,基本类型(int)和基本类型的包装类(Integer)是不同的类型
操作构造函数
1 2 3
   | Constructor<?> constructor = classStu.getConstructor(null); 		Student stu = (Student)constructor.newInstance(); 		System.out.println(stu);
   | 
 
动态加载类名和方法
1 2
   | classname=reflect.Student methodname=staticMethod
   | 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
   | Properties prop = new Properties(); 		prop.load(new FileReader("class.txt")); 		 		String classname = prop.getProperty("classname"); 		String methodname = prop.getProperty("methodname"); 		 		Class<?> classStu = null; 		//反射入口 		try { 			classStu = Class.forName(classname); 		} catch (ClassNotFoundException e) { 			e.printStackTrace(); 		} 		 		Method method = classStu.getMethod(methodname); 		method.setAccessible(true); 		method.invoke(classStu.newInstance());
   | 
 
通过反射越过泛型检查
1 2 3 4 5 6 7 8 9
   | ArrayList<Integer> list = new ArrayList(); 		list.add(123); 		list.add(22); 		 		 Class<?> classStu = list.getClass(); 		 		Method method = classStu.getMethod("add", Object.class); 		method.invoke(list, "ssss"); 		System.out.println(list);
   | 
 
注:虽然可以通过反射访问等访问修饰符不允许访问的属性和方法,也可以忽略掉泛型检查,但不推荐使用,可能会引起程序的混乱
通过反射实现万能set方法
- obj:对象
 
- propertyName:属性名
 
- value:属性值
 
1 2 3 4 5 6 7 8
   | public static void setProperty(Object obj, String propertyName, Object value) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { 		 		Class<?> clazz = obj.getClass(); 		Field field = clazz.getDeclaredField(propertyName); 		field.setAccessible(true); 		field.set(obj, value); 		 	}
  | 
 
         
        
    
    
        
    最后更新时间:
        
        谢谢阅读本文,如果对文章或者网站有什么建议,请发邮件到:1799623289@qq.com