反射

JAVA反射机制是在运行状态中

对于任意一个类,都能够知道这个类的所有属性和方法;

对于任意一个对象,都能够调用它的任意一个方法和属性;

这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

 1)获取Class对象的三种方式

//Object类中的getObject()方法
Person person = new Person();
Class c1 = person.getClass();
System.out.println(c1);
	
//类名.class 获取到字节码文件对象	
Class c2 = Person.class;
System.out.println(c2);
		
//通过Class类中的方法
Class c3 = Class.forName("cn.it.ref.Person");
System.out.println(c3);
		
System.out.println(c1==c2);//T
System.out.println(c1==c3);//T
System.out.println(c3==c2);//T

2)通过反射获取构造方法并使用

@Test
	public void func1() throws Exception{
		Class c1 = Class.forName("cn.it.ref.Person");
		
		//  获取所有的public 修饰的构造方法
		/*Constructor[] constructors = c1.getConstructors();
		for (Constructor constructor : constructors) {
			System.out.println(constructor);
		}*/
		
		//获取public修饰, 指定参数类型所对应的构造方法。
        //不传参数得到无参构造方法
		//获取指定的构造方法,空参数的构造方法
		Constructor constructor = c1.getConstructor();
		System.out.println(constructor);//public cn.it.ref.Person()
		
		//运行空参数构造方法,Constructor类方法 newInstance()运行获取到的构造方法
		Object obj = constructor.newInstance();
		System.out.println(obj);//Person [name=null, age=null]
		
		Constructor constructor2 = c1.getConstructor(String.class,Integer.class);
		System.out.println(constructor2);//public cn.it.ref.Person(java.lang.String,java.lang.Integer)
		
		Object obj1 = constructor2.newInstance("jackson",20);
		System.out.println(obj1);//Person [name=jackson, age=20]
		
		//前提: 类有空参的公共构造方法,构造方法权限必须public
		Object obj2 = c1.newInstance();
		System.out.println(obj2);//Person [name=null, age=null]
		
		//反射获取私有的构造方法运行
		Constructor declaredConstructor = c1.getDeclaredConstructor(Integer.class,String.class);
		//Constructor类,父类AccessibleObject,定义方法setAccessible(boolean b)
		declaredConstructor.setAccessible(true);
		Object newInstance = declaredConstructor.newInstance(21,"john");
		System.out.println(newInstance);//Person [name=john, age=21]
	}

3)反射获取成员变量并改值

        @Test
	public void func2() throws Exception{
		Class c = Class.forName("cn.it.ref.Person");
		Object obj = c.newInstance();
		//获取成员变量 Class类的方法 getFields() class文件中的所有公共的成员变量
		Field[] fields = c.getFields();
		for (Field field : fields) {
			System.out.println(field);//public java.lang.String cn.it.ref.Person.name
		}
		
		//获取指定的成员变量 String name
		Field field = c.getField("name");
		field.set(obj, "jackson");
		System.out.println(obj);//Person [name=jackson, age=null]
		
	}

4)反射获取成员方法并运行

        @Test
	public void func3() throws Exception{
		Class c = Class.forName("cn.it.ref.Person");
		Object obj = c.newInstance();
		// Method[] getMethods()获取的是class文件中的所有公共成员方法,包括继承的
		Method[] methods = c.getMethods();
		for (Method method : methods) {
			System.out.println(method);
		}
		
		Method method = c.getMethod("method1");
		//obj 指的是调这个方法的对象。
		//args 指的是调用这个方法所要用到的参数列表。
		//返回值Object就是方法的返回对象。如果方法没有返回值 ,返回的是null.
		method.invoke(obj);//method1
		
		//返回一个 Method 对象,它反映此 Class 对象所表示的类或接口的指定公共成员方法
		Method method1 = c.getMethod("method1", String.class);
		method1.invoke(obj, "123456");//method1..123456
	}

5)用反射的方法绕过编译,得到Class文件对象,直接调用add方法

反射泛型擦除 java中的泛型是 伪泛型
伪泛型:在编译后的.class文件里面是没有泛型的。类型为Object

        @Test
	public void func4() throws Exception{
		List<String> list = new ArrayList<String>();
		list.add("jack");
		//反射方式,获取出集合ArrayList类的class文件对象
		Class c = list.getClass();
		//获取ArrayList.class文件中的方法add
		Method method = c.getMethod("add", Object.class);
		method.invoke(list, "lucy");
		method.invoke(list, 21);
		method.invoke(list, 22);
		System.out.println(list);
	}

6)反射配置文件

pro.properties:

#className=cn.it.ref.Worker
#classMethod=work
className=cn.it.ref.Student
classMethod=student
	@Test
	public void func5() throws Exception{
		//IO流读取配置文件
		FileReader fr = new FileReader("src/pro.properties");
		//创建集合对象
		Properties properties = new Properties();
		//调用集合方法load,传递流对象
		properties.load(fr);
		//关闭流
		fr.close();
		//通过键获取值
		String className = properties.getProperty("className");
		String classMethod = properties.getProperty("classMethod");
		//反射获取指定类的class文件对象
		Class c = Class.forName(className);
		Object newInstance = c.newInstance();
		//获取指定的方法名
		Method method = c.getMethod(classMethod);
		method.invoke(newInstance);
	}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值