JAVA 反射的作用和具体的使用

java 反射

反射十分强大,可以调用知道任何类,方法,属性,反射是框架的灵魂
1.要反射当然要先找到入口有3种方法获得入口

对象.getclass()

Parson ps=new Parson();

Class<?> cl= ps.getClass();

Class.forName("包名.类名")

Class<?> forName = Class.forName(“Reflect.parson”);

类名class

Class<?> clazz= parson.class;

有了这3种方法,就可以体验反射的强大了

2.反射可以干嘛

1获取公共方法 getMethods()&获取当前类的所有方法getDeclaredMethods() ★

公共方法:获取公共的方法(本类,父类,接口,符合访问修饰符的类)

当前类的所有方法:只能的当前类,忽略修饰符(private也可以访问)

private static void demo2() throws ClassNotFoundException {
    
    
		//先获取入口
		Class<?> forName = Class.forName("Reflect.parson");
		//获取公共方法
		Method[] methods = forName.getMethods();
		for (Method method : methods) {
    
    
			System.out.println(method);
		}
		System.out.println("===================");
    //获取当前类的所有方法(1,只能的当前类,忽略修饰符(private也可以访问))
		Method[] declaredMethods = forName.getDeclaredMethods();
		for (Method method : declaredMethods) {
    
    
			System.out.println(method);
		}

2,获取接口 getInterfaces() ★

private static void demo3() throws ClassNotFoundException {
    
    
		Class<?> forName = Class.forName("Reflect.parson");
		Class<?>[] interfaces = forName.getInterfaces();
		for (Class<?> class1 : interfaces) {
    
    
			System.out.println(class1);
		}
	}

3,获取 父类 getSuperclass()

private static void demo4() throws ClassNotFoundException {
    
    
		Class<?> forName=Class.forName("Reflect.parson");
		 Class<?> superclass = forName.getSuperclass();
		 System.out.println(superclass);
	}

4,获取构造方法 getConstructors() ★

private static void demo5() throws ClassNotFoundException {
    
    
		Class<?> forName = Class.forName("Reflect.parson");
		 Constructor<?>[] constructors = forName.getConstructors();
		 for (Constructor<?> constructor : constructors) {
    
    
			System.out.println(constructor);
		}
	}

5获取属性 getFields() ★

private static void demo6() throws ClassNotFoundException {
    
    
		Class<?> forName = Class.forName("Reflect.parson");
		Field[] fields = forName.getFields();
		for (Field field : fields) {
    
    
			System.out.println(field);
		}
	}

6获取当前反射所代表类(接口) 的对象(实例) newInstance( ★

private static void demo7() throws ClassNotFoundException, InstantiationException, IllegalAccessException {
    
    
		Class<?> forName = Class.forName("Reflect.parson");
		Object newInstance = forName.newInstance();
		parson ps=(parson)newInstance;
		ps.InterfaceMethod();//获取parson 的实例,调用方法
	}
3反射的具体使用

获取对象实例,并操作对象,操作方法

// 获取对象实例,并操作对象
		Class<?> forName = Class.forName("Reflect.parson");
		// 1获取对象
		parson parson = (parson) forName.newInstance();
		parson.setName("weng");
		System.out.println(parson.getName());
		System.out.println("============================");
		// 操作属性

		// Field field = forName.getField("id");//不能访问私有的,只能的公共的
		Field field = forName.getDeclaredField("id");
		// 开启权限
		// 修改属性的访问权限 使用反射时,如果 因为访问修饰符限制造成异常,
		// 可以通过 Field/Method/Constructor.setAccessible(true)
		field.setAccessible(true);//
		field.set(parson, 1);
		System.out.println(parson.getId());
		System.out.println("==============================");
		// 操作方法
		Method method = forName.getDeclaredMethod("InterfaceMethod", null);
		method.invoke(parson, null);// 方法的调用:invoke()
		System.out.println("=============");
		// 有参数类型的
		Method method2 = forName.getDeclaredMethod("testname", String.class);
		method2.setAccessible(true);
		method2.invoke(parson, "weng");
		System.out.println("=================");
		// 操作构造方法
		// 获取指定的构造方法
		// 在反射中,根据类型 获取方法时:基本类型(int、char...)和包装类(Integer,Character)是不同的类型
		Constructor<?> constructor1 = forName.getConstructor(null);
		System.out.println(constructor1);
		Constructor<?> constructor2 = forName.getDeclaredConstructor(int.class);
		System.out.println(constructor2);
		// 根据获取的private构造方法,获取对象实例
		parson instance2 = (parson) constructor2.newInstance(1);
		System.out.println(instance2);
		parson par = (parson) constructor1.newInstance();
		System.out.println(par);

动态加载 类名 和方法

1,先创建prop.txt 文件

classname=Reflect.parson//类名
methodname=InterfaceMethod//方法名

2,进行操作

public static void demo2() throws FileNotFoundException, IOException, ClassNotFoundException,
			IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException,
			NoSuchMethodException, SecurityException {
    
    
		Properties prop = new Properties();
		// 加载属性文件
		prop.load(new FileReader("prop.txt"));
		// 读取属性
		String classname = prop.getProperty("classname");
		String methodname = prop.getProperty("methodname");
		
		Class<?> forName = Class.forName(classname);//反射入口
		Method method = forName.getMethod(methodname);//获取方法
		Object instance = forName.newInstance();//创建实例
		method.invoke(instance);//调用实例
	}

反射可以越过泛型的检查

public static void demo3() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
    
    
		List<Integer> list=new ArrayList<Integer>();
		list.add(123);
		list.add(2);
		Class<?> rf= list.getClass();
		Method method = rf.getMethod("add",Object.class);//修改方法参数类型为Object
		method.invoke(list, "weng");
		System.out.println(list);
	}

万能的set方法

1,创建PropertyUtil

/**
	 * 
	 * @param obj //对象
	 * @param propertyName //set属性
	 * @param value //设置值
	 * @throws SecurityException 
	 * @throws NoSuchFieldException 
	 * @throws IllegalAccessException 
	 * @throws IllegalArgumentException 
	 */
	public static void setPropertys(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);
	}
public static void demo4() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
    
    
		Student student=new Student();
		PropertyUtil.setPropertys(student, "name", "weng");
		System.out.println(student.getName());
	}
4小结

访问私有的方法使用 getDeclared***();

修改属性的访问权限 使用反射时,如果 因为访问修饰符限制造成异常,
可以通过 Field/Method/Constructor.setAccessible(true)
field.setAccessible(true);

猜你喜欢

转载自blog.csdn.net/weng74/article/details/100119729
今日推荐