java反射

反射技术

反射技术一般用来作框架使用。框架一般都是都是通过读取配置文件来运行指定类文件。

反射就是加载类,并解剖类的各个组成部分。

Class常用method(省略参数列表)

getConstructor()getMethod()getField()

getDeclaredConstructor()getDeclareMethod()getDeclareField()

区别:

没有declared的只能获取类中的public的声明部分,使用declared能获得private的声明部分。

 

反射类的Constructor示例:

 

package com.summer.day1;

public class Person {
	private int age=10;
	private String name= "aaa";
	
	
	public Person() {
		super();
		System.out.println(age+name);
	}


	public Person(int age, String name) {
		super();
		this.age = age;
		this.name = name;
		System.out.println(age+name);
	}


	private Person(String name) {
		super();
		this.name = name;
		System.out.println(age+name);
	};
	
	public void eat(String food){
		System.out.println(food);
	}
	
	public static String run(String run){
		System.out.println(run);
		return run+" faster";
	}
	
	public static void main(String[] args){
		System.out.println("main");
	}
	
	
	
}
package com.summer.day1;

import java.lang.reflect.Constructor;

import org.junit.Test;

public class Refelct {

	@Test
	public void test1() throws Exception{
		Class clazz= Class.forName("com.summer.day1.Person");
		Constructor constructor=clazz.getConstructor(null);
		constructor.newInstance();
	}
	
	
	@Test
	public void test2() throws Exception{
		Class clazz= Class.forName("com.summer.day1.Person");
		//如果使用getConstructor则由于private权限问题会在下面一句报错
		Constructor constructor=clazz.getDeclaredConstructor(String.class);
		//没有设置成true则在newInstance时报错
		constructor.setAccessible(true);
		constructor.newInstance("bbb");
	}
	
	@Test
	public void test3() throws Exception{
		Class clazz= Class.forName("com.summer.day1.Person");
		//本质是test1,找到无参构造函数,然后newInstance
		//算是test1的简写形式
		clazz.newInstance();
	}
	
}


 

反射类的Method示例:

 

package com.summer.day1;

import java.lang.reflect.Method;

import org.junit.Test;

public class MethodDemo {

	@Test
	public void test1() throws Exception{
		Class clazz= Class.forName("com.summer.day1.Person");
		//指明函数名和传递参数列表
		Method method = clazz.getMethod("eat", String.class);
		Person p=new Person();
		//指明调用的对象和参数值
		method.invoke(p, "apple");
	}
	@Test
	public void test2() throws Exception{
		Class clazz= Class.forName("com.summer.day1.Person");
		Method method = clazz.getMethod("run", String.class);
		//如果方法为静态的可以不需要指定调用的对象,用null
		//方法的结果为invoke的返回结果
		String ans=(String) method.invoke(null, "run");
		System.out.println(ans);
	}
	
	
	@Test
	/**
	 * 调用main方法需要注意main(String[] args)的参数传递
	 * 这是因为在jdk1.5前没有可变参数所引起的,没有可变参数前是invoke(Object,Object[]),
	 * 他会将值列表Object[]中的内容提取出来然后根据函数名和参数列表去找对应的method
	 * 因此method.invoke(null, new String[]{"aa","bb"});会被认为是去寻找main(String,String)
	 * 所以找不到,现实参数列表的个数错误
	 * @throws Exception
	 */
	public void test3() throws Exception{
		Class clazz= Class.forName("com.summer.day1.Person");
		Method method = clazz.getMethod("main", String[].class);
		/*
		 * method.invoke(null, new String[]{"aa"});
		 *这个居然显示参数类型不匹配,只有一个值的数组居然不可以
		 */
		/*
		 * method.invoke(null, new String[]{"aa","bb"});
		 * 这个现实参数列表的个数错误
		 */
		/* method.invoke(null, (Object)new String[]{"aa","bb"});
		 * 这样将数组变为了类,invoke不需要去提取类中的内容,所以能通过
		 **/
		 method.invoke(null, new Object[]{new String[]{"aa","bb"}});
	}
	
	

}

反射类的Field类似,主要方法get()set()方法类似于ConstructornewInstanceMethodinvoke方法。对于私有的field可以使用getDeclareField()得到,但是如果想get的话要先修改setAccessibletrue)。字段如果不是static,则在get字段时需要指明是那个实力的field

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值