java反射

反射:在运行状态下,通过class文件对象,去使用构造方法,成员变量,成员方法

获取class文件(字节码对象)

方式1 通过Object类的getClass方法

		Person p = new Person();
		Class c1 = p.getClass();

		Person p2 = new Person();
		Class c2 = p2.getClass();

		System.out.println(p == p2);
		System.out.println(c1 == c2);  //true 一个类的字节码对象只有一个

方式2 任意对象的静态的class属性

Class c3 = Person.class;

方式3 通过Class类的静态方法forName()

Class c4 = Class.forName("com.reflect.Person");

反射获取构造方法

  • Constructor[] Class.getConstructors() : 返回公共构造方法
  • Constructor[] Class.getDeclaredConstructors() : 返回所有构造方法(包含私有)
  • Constructor Class.getConstructor() : 可变参数,此处获取无参构造方法
  • Constructor.newInstance() :构造器创建对象
		//1.获取字节码文件对象
		Class c = Class.forName("com.reflect.Person");

		//2.获取构造器对象
//		Constructor[] cons = c.getConstructors();  //返回公共构造方法
//		for(Constructor con:cons){
//			System.out.println(con);
//		}
//		cons = c.getDeclaredConstructors();        //返回所有构造方法(包含私有)
//		for(Constructor con:cons){
//			System.out.println(con);
//		}
		Constructor con = c.getConstructor();    //可变参数,此处获取无参构造方法
		System.out.println(con);
		Constructor con2 = c.getConstructor(String.class, int.class);//获取带参构造函数
		System.out.println(con2);

		//3.通过构造器对象创建对象
		Object obj = con.newInstance();
		System.out.println(obj);
		Object obj2 = con2.newInstance("xyg", 24);
		System.out.println(obj2);

反射获取成员变量

  • Field[] Class.getFields() : 获取Public成员变量
  • Field[] Class.getDeclaredFields() : 获取所有成员变量(包括私有)
  • Field Class.getField(String) : 获取单个成员变量
  • Field Class.getDeclaredField(String) : 获取单个私有成员
		//1.获取字节码对象
		Class c = Class.forName("com.reflect.Person");

		//2.获取成员变量对象
		Field[] fields = c.getFields();//获取Public成员变量
		for(Field f:fields){
			System.out.println(f);
		}
		System.out.println("----");
		fields = c.getDeclaredFields();//获取所有成员变量
		for(Field f:fields){
			System.out.println(f);
		}

		Field ageField = c.getField("age");//获取单个成员变量
		
		Field nameField = c.getDeclaredField("name");//获取单个私有成员
		nameField.setAccessible(true);//设置为true才能访问


		//3.通过Field对象设置成员值
		Constructor con = c.getConstructor();
		Object obj = con.newInstance(); //构造器构造对象
		ageField.set(obj, 12);//给obj对象的field字段赋值12
		nameField.set(obj, "xyg");
		
		System.out.println(obj);

反射获取类成员方法

  • Method[] Class.getMethods() : 获取所有公共方法,包括父类方法
  • Method[] Class.getDeclaredMethods() : 获取本类的所有方法(不包括父类)
  • Method Class.getMethod() : 获取单个方法,无参传递null
  • Method Class.getDeclaredMethod() : 获取私有方法
		//1.获取字节码对象
		Class c = Class.forName("com.reflect.Person");
		Constructor con = c.getConstructor();
		Object obj = con.newInstance();
		
		//2.获取方法
		Method[] methods = c.getMethods();//获取所有公共方法,包括父类方法
		for(Method m:methods){
			System.out.println(m);
		}
		System.out.println("-----");
		methods = c.getDeclaredMethods();//获取本类的所有方法(不包括父类)
		for(Method m:methods){
			System.out.println(m);
		}

		Method m1 = c.getMethod("show", null);//获取单个无参方法
		m1.invoke(obj, null);//无参传递null
		Method m2 = c.getMethod("function", String.class);//获取单个有参方法
		m2.invoke(obj, "xyg");
		Method m3 = c.getMethod("returnValue", String.class,int.class);//夺取多参有返回值
		System.out.println(m3.invoke(obj, "林青霞",38));
		Method m4 = c.getDeclaredMethod("hello",null);//获取私有方法
		m4.setAccessible(true);//设置为true
		m4.invoke(obj, null);

应用

使用反射越过泛型jianc

		ArrayList<Integer> list = new ArrayList<>();
		list.add(24);
		list.add(432);
//		list.add("fdjsl");ERROR
		Class c = list.getClass();
		Method m = c.getDeclaredMethod("add", Object.class);//这里要接受Object的字节码
		m.invoke(list, "hello");
		m.invoke(list, "world");
		System.out.println(list);
原文地址:https://www.cnblogs.com/xiongyungang/p/12653650.html