java反射知识点小结

参考代码:https://github.com/ZhangXiaoixiang/reflectdemo

说明:收集的网上资料,自己整理收集

视频教程(腾讯课堂): https://ke.qq.com/webcourse/index.html#cid=298879&term_id=100354189&taid=2094161629319039&vid=t1426y3hmoz
视频教程(网易云课堂): https://study.163.com/course/courseLearn.htm?courseId=1005927016#/learn/video?lessonId=1053358058&courseId=1005927016

下面的2个步骤是反射的基本操作

1:反射获取类相关

package com.demo;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
//QQ交流群:181736667
//视频教程(腾讯课堂): https://ke.qq.com/webcourse/index.html#cid=298879&term_id=100354189&taid=2094161629319039&vid=t1426y3hmoz
//视频教程(网易云课堂): https://study.163.com/course/courseLearn.htm?courseId=1005927016#/learn/video?lessonId=1053358058&courseId=1005927016
/**
 * 反射获取类相关
 */
public class ReflectDemo01 {
	//通过反射获取类
	public static void demo01() {
		//获取反射对象(反射入口):Class ,1 Class.forName(全类名)   2 类名.class  3 对象.getClass()
		//1 Class.forName("全类名")
		try {
			Class<?> perClazz =  Class.forName("reflect.Person") ;
			System.out.println(perClazz);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		
//		 2 类名.class
		Class<?> perClazz2 = Person.class ;
		System.out.println(perClazz2);
		
//		 3 对象.getClass()
		Person per = new Person();
		Class<?> perClazz3 = per.getClass() ;
		System.out.println(perClazz3);
	}
 
	//获取公共方法
	public static void demo02() {
		//Class入口
		Class<?> perClazz =  null ; 
		try {
			perClazz =  Class.forName("reflect.Person") ;
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		//获取所有的 公共的方法(1.本类 以及 父类、接口中的所有方法  2.符合访问修饰符规律)
		  Method[] methods = perClazz.getMethods();
		  for(Method method:methods) {
			  System.out.println(method);
		  }
		  System.out.println("==========");
		  //获取当前类的所有方法(1.只能是当前类   2.忽略访问修饰符限制)
		  Method[] declaredMethods = perClazz.getDeclaredMethods();
		  for(Method declaredMethod:declaredMethods) {
			  System.out.println(declaredMethod);
		  }
	}
	
	//获取所有的接口
	public static void demo03() {
		Class<?> perClazz =  null ; 
		try {
			perClazz =  Class.forName("reflect.Person") ;
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		
		Class<?>[] interfaces = perClazz.getInterfaces() ;
		for(Class<?> inter:interfaces) {
			System.out.println(inter);
		}
	}
	
	//获取所有的父类
		public static void demo04() {
			Class<?> perClazz =  null ; 
			try {
				perClazz =  Class.forName("reflect.Person") ;
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			}
			Class<?> superclass = perClazz.getSuperclass() ;
			System.out.println(superclass);
			
		}
	
		
		//获取所有的构造方法
		public static void demo05() {
			Class<?> perClazz =  null ; 
			try {
				perClazz =  Class.forName("reflect.Person") ;
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			}
			Constructor<?>[] constructors = perClazz.getConstructors() ;
			for(Constructor<?> constructor:constructors) {
				System.out.println(constructor);
				
			}
		}
	
		//获取所有的公共属性
		public static void demo06() {
			Class<?> perClazz =  null ; 
			try {
				perClazz =  Class.forName("reflect.Person") ;
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			}
			//公共属性
			Field[] fields = perClazz.getFields() ;
			for(Field field:fields) {
				System.out.println(field);
			}
			System.out.println("====");
			//所有属性  (属性的 :公共属性\所有属性的区别 同“方法”)
			Field[] declaredFields = perClazz.getDeclaredFields() ;
			for(Field declaredField:declaredFields) {
				System.out.println(declaredField);
			}
		}
	
	//获取当前反射所代表类(接口) 的对象(实例)
	public static void demo07() throws InstantiationException, IllegalAccessException {
		Class<?> perClazz =  null ; 
		try {
			perClazz =  Class.forName("reflect.Person") ;
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		
		Object instance = perClazz.newInstance() ;
		Person per = (Person)instance ;
		per.interface2Method(); 
	}
	
	
	
	public static void main(String[] args) throws InstantiationException, IllegalAccessException {
//		demo01();
//		demo02();
//		demo03();
//		demo04();
//		demo05();
//		demo06();
		demo07();
	}

}

2:反射获取类的实例,并操作

package com.demo;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Properties;

/**
 * 反射获取类的实例,并操作
 */
public class ReflectDemo02 {
	//获取对象的实例,并操作对象
	public static void demo01() throws InstantiationException, IllegalAccessException {
			Class<?> perClazz =  null ; 
			try {
				perClazz =  Class.forName("reflect.Person") ;
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			}
			Person per = (Person)perClazz.newInstance() ;
			per.setName("zs");
			per.setAge(23);
			System.out.println(  per.getName()+","+per.getAge());
	}
	
	//操作属性
	public static void demo02() throws InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException {
		Class<?> perClazz =  null ; 
		try {
			perClazz =  Class.forName("reflect.Person") ;
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		
		Person per = (Person)perClazz.newInstance() ;
		Field idField = perClazz.getDeclaredField(  "id");
		//访问的是private修饰的id,但是private是私有
		//修改属性的访问权限  使用反射时,如果 因为访问修饰符限制造成异常,可以通过  Field/Method/Constructor.setAccessible(true)
		idField.setAccessible(true);
		idField.set(per, 1);   //per.setId(1);
		System.out.println( per.getId() );
		
		System.out.println("=====");
		Method method = perClazz.getDeclaredMethod("privateMethod", null) ;
		method.setAccessible(true);
		method.invoke(per,null )  ;//方法的调用:invoke()
		//per.say(xxx);
		
		Method method2 = perClazz.getDeclaredMethod("privateMethod2", String.class) ;
		method2.setAccessible(true);
		method2.invoke(per, "zs") ;
		
	}

	//操作构造方法
	public static void demo03() throws InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException {
		Class<?> perClazz =  null ; 
		try {
			perClazz =  Class.forName("reflect.Person") ;
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		
//		Constructor<?>[] constructors = perClazz.getConstructors() ;//公共
//		for(Constructor constructor:constructors) {
//			System.out.println(constructor);
//		}
		
//		Constructor<?>[] constructors = perClazz.getDeclaredConstructors() ;//本类
//		for(Constructor constructor:constructors) {
//			System.out.println(constructor);
//		}
		
		//获取指定的构造方法  
		//在反射中,根据类型 获取方法时:基本类型(int、char...)和包装类(Integer,Character)是不同的类型
		Constructor<?> constructor = perClazz.getConstructor(Integer.class) ;
		System.out.println(constructor);
		
		Constructor<?> constructor2 = perClazz.getDeclaredConstructor(String.class) ;
		System.out.println(constructor2);
		//Person per = new Person() ;
		
		
		//根据获取的private构造方法,获取对象实例
		constructor2.setAccessible(true);
		Person per3 = (Person)constructor2.newInstance("zs") ;
		System.out.println("per3"+per3);
		
		Person instance2 = (Person)constructor.newInstance(23) ;//因为constructor是 有参构造方法(Integer),因此需要传入一个Integer值
		System.out.println(instance2);
		
		Constructor<?> constructor3 = perClazz.getConstructor() ;
		Person instance = (Person)constructor3.newInstance( ) ;//因为constructor3是 无参构造方法,因此不需要传值
		
		System.out.println(instance);
	}
	
	//动态加载 类名 和方法
	public static void demo04() throws InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException, FileNotFoundException, IOException {
		
		Properties prop = new Properties();
		prop.load(   new FileReader("class.txt") );
		
		String classname = prop.getProperty("classname") ;
		String methodname = prop.getProperty("methodname") ;
		
		Class<?> perClazz =  null ; 
		try {
			perClazz =  Class.forName(classname) ;
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		
		Method method = perClazz.getMethod(methodname) ;
		method.invoke( perClazz.newInstance()  ) ;
		
	}
	
	//反射可以 越过泛型检查 
	//虽然可以通过反射 访问private等访问修饰符不允许访问的属性/方法,也可以忽略掉泛型的约束;但实际开发 不建议这样使用,因此可能造成程序的混乱。
	public static void demo05() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException {
		ArrayList<Integer> list = new ArrayList<>() ;
		list.add(123) ;
		list.add(3) ;
		list.add(2) ;
//		list.add("zs") ; 
		
		Class<?> listClazz = list.getClass() ;
		Method method = listClazz.getMethod("add", Object.class) ;
		method.invoke(list , "zs...") ;
		System.out.println(list);
	}
	
	public static void demo06() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
		Person per = new Person();
		PropertyUtil.setProperty(per, "name", "zs");
		PropertyUtil.setProperty(per, "age", 23);
		Student stu  = new Student() ;
		PropertyUtil.setProperty(stu, "score", 98);
		
		System.out.println(per.getName()+","+per.getAge());
		System.out.println(stu.getScore());
	}
	
	public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException, FileNotFoundException, IOException {
//		demo01() ;
//		demo02() ;
//		demo03() ;
		demo04() ;
//		demo05() ;
//		demo06() ;
	}
}

涉及到的类或文本

接口1

package com.demo;

/**
 * 单纯的接口
 */
public interface MyInterface {
	void interfaceMethod() ;
}

接口2

package com.demo;

/**
 * 单纯的接口
 */
public interface MyInterface2 {
	void interface2Method() ;
}

对象1

package com.demo;

/**
 * 用于反射的一个类
 */
public class Person  implements MyInterface,MyInterface2{
	private int id;
	private String name ;
	private int age ; 
	
	public String desc ;
	
	private Person(String name) {
		this.name = name;
	}
	
	public Person() {
	}
	public Person(Integer id) {
		this.id = id;
	}
	
	public Person(int id, String name, int age) {
		this.id = id;
		this.name = name;
		this.age = age;
	}

	public int getId() {
		return id;
	}
	
	public void setId(int id) {
		this.id = id;
	}

	
	public void setName(String name) {
		this.name = name;
	}
	
	
	public String getName() {
		return name;
	}

	public int getAge() {
		return age;
	}
	
	private void privateMethod() {
		System.out.println(" private method...");
	}
	
	private void privateMethod2(String name) {
		System.out.println(" private method2..."+name);
	}


	public void setAge(int age) {
		this.age = age;
	}
	public static void staticMethod() {
		System.out.println("static  method ...");
	}
	
	@Override
	public void interfaceMethod() {
		System.out.println("interface  Method....");
	}
	@Override
	public void interface2Method() {
		System.out.println("interface2  Method....");
		
	}

}

对象2

package com.demo;

/**
 * 用于反射的另一个类
 */
public class Student {
	private int score ;
	
	public int getScore() {
		return score ; 
	}
	public void sayHi() {
		System.out.println("I am a student....");
	}
}

工具类

package com.demo;

import java.lang.reflect.Field;

/**
 * 万能的setXxx()方法,当然getXxx()也行
 */
public class PropertyUtil {
	// per.setXxx(value); private String name;
	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);
	}
}

文本class.txt  (相当于properties,文本里面写键值对的格式)

classname=com.demo.Student
methodname=sayHi

代码结构截图

发布了57 篇原创文章 · 获赞 33 · 访问量 814万+

猜你喜欢

转载自blog.csdn.net/wozniakzhang/article/details/89814231