反射

一个类是有多个部分组成的,如构造函数.字段.属性.方法等;

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

编程是什么情况下才需要加载类,并解剖出类的各个组成部分呢?

一般框架是基于配置文件的,首先,配置文件需要获得当前类,然后再解剖类中的方法.

反射是java中很重要的一门技术,如果这部分学不明白,那么以后框架就很难学明白了.

加载类通过Class.forName(类的完整限定名);按F2可获得此类的完整限定名.

//反射:加载类,获得Class
		方式一:
		Class cla1= Class.forName("gw.reflect.Person");
		方式二:
		Class cla2 = new Person().getClass();
		方式三:
		Class cla3 = Person.class;
		
		System.out.println(cla1);

Class对象提供了如下常用的方法

Constructor<T>getConstructor(Class<?>... parameterTypes)
返回一个 Constructor 对象,它反映此 Class 对象所表示的类的指定公共构造方法。

MethodgetMethod(String name,Class<?>... parameterTypes)
返回一个 Method 对象,它反映此 Class 对象所表示的类或接口的指定公共成员方法。

Field[]getFields()
返回一个包含某些 Field 对象的数组,这些对象反映此 Class 对象所表示的类或接口的所有可访问公共字段。
这些方法分别用于从类中解剖出构造函数.方法和成员变量(属性),解剖出的成员分别使用Constructor.Method.Field对象表示.

以上方法仅限于获得类中的public修饰的成员,对于其他修饰的则无法获得.

想要获得的话,需要使用如下方法才可.

Constructor<T>getDeclaredConstructor(Class<?>... parameterTypes)
返回一个 Constructor 对象,该对象反映此 Class 对象所表示的类或接口的指定构造方法。

FieldgetDeclaredField(String name)
返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段。

MethodgetDeclaredMethod(String name,Class<?>... parameterTypes)
返回一个 Method 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明方法。
获得构造函数

	@Test
	// public Person()
	public void test1() throws Exception {
		// 加载类
		Class clazz = Class.forName("gw.reflect.Person");
		// 获得无参的构造函数,无参用null表示
		Constructor con = clazz.getConstructor(null);
		// 有了构造函数就可以实例化该类的一个对象
		Person p = (Person) con.newInstance(null);

		System.out.println(p.name);

	}
	@Test
	// public Person(String name)
	public void test2() throws Exception {
		Class clazz = Class.forName("gw.reflect.Person");
		// java中都是用类表示的
		Constructor con = clazz.getConstructor(String.class);
		Person p = (Person) con.newInstance("gg");
		System.out.println(p.name);

	}

	@Test
	// public Person(String name,int age)
	public void test3() throws Exception {
		Class clazz = Class.forName("gw.reflect.Person");
		Constructor con = clazz.getConstructor(String.class, int.class);
		Person p = (Person) con.newInstance("ff", 12);
		System.out.println(p.name);
	}

	@Test
	// private Person(List list)
	public void test4() throws Exception {
		Class clazz = Class.forName("gw.reflect.Person");
		// 获得类中的私有构造函数
		Constructor con = clazz.getDeclaredConstructor(List.class);
		con.setAccessible(true);// 私有构造函数的获得需要先暴力反射
		Person p = (Person) con.newInstance(new ArrayList());
		System.out.println(p.name);
	}

  
 @Test
    // public Person()
    public void test5() throws Exception {
        Class clazz = Class.forName("gw.reflect.Person");
        // sun公司提供的通过class实例化类的对象的一个方法
        Person p = (Person) clazz.newInstance();
        p.eat();
    }

获得方法

	@Test
	// public void aa1()
	public void test1() throws Exception {
		Person p = new Person();
		// 加载类
		Class clazz = Class.forName("gw.reflect.Person");
		// 获得方法getMethod(方法名,参数列表)
		Method me = clazz.getMethod("aa1", null);
		// 方法的调用invoke(对象,参数)
		me.invoke(p, null);

	}

	@Test
	// public void aa1(String name, int age)
	public void test2() throws Exception {
		// 对象
		Person p = new Person();
		// 加载类
		Class clazz = Class.forName("gw.reflect.Person");
		// 获得方法getMethod(方法名,类)
		Method me = clazz.getMethod("aa1", int.class);
		// 调用方法
		me.invoke(p, 13);
	}

	@Test
	// public Class[] aa1(String name,int[] age)
	public void test3() throws Exception {
		Person p = new Person();
		// 加载类
		Class clazz = Class.forName("gw.reflect.Person");
		// 获得方法
		Method me = clazz.getMethod("aa1", String.class, int[].class);
		//
		Class[] cs = (Class[]) me.invoke(p, "gg", new int[] { 1, 2, 3 });
		System.out.println(cs[0]);

	}

	@Test
	// public void aa1(InputStream in)
	public void test4() throws Exception {
		Person p=new Person();
		Class clazz = Class.forName("gw.reflect.Person");
		Method me = clazz.getMethod("aa1", InputStream.class);
		me.invoke(p,new FileInputStream("w:\\1.txt"));
	}


	@Test
	// public static void aa1(int num)
	public void test5() throws Exception {
		// 加载类
		Class clazz = Class.forName("gw.reflect.Person");
		// 获得方法getMethod(方法名,类)
		Method me = clazz.getMethod("aa1", int.class);
		// 调用方法invoke(对象,参数值)
		me.invoke(null, 12);
	}
主方法
	@Test
        //public static void main(String[] args)
	public void test() throws Exception{
	
		Person p = new Person();
		Class clazz = Class.forName("gw.reflect.Person");
		Method me=clazz.getMethod("main", String[].class);
		//反射调用一个接收数组的方法时,为了保证向下兼容性,它会先拆数组
		//方式一:new Object[]{参数}
		//方式二:Object(参数)
		me.invoke(p,new Object[]{ new String[]{"aa","bb"}});
	}

获取字段

	
	@Test
	// public String name = "gw";
	public void test1() throws Exception {
		Person p = new Person();
		Class clazz = Class.forName("gw.reflect.Person");
		Field f = clazz.getField("name");
		// 获取字段的值
		String value = (String) f.get(p);

		// 获取字段的类型
		Class type = f.getType();
		if (type.equals(String.class)) {
			String fv = (String) value;
			System.out.println(fv);
		}

	@Test	//private int age = 15;
	public void test2() throws Exception {
		Person p= new Person();
		Class clazz = Class.forName("gw.reflect.Person");
		//获取public之外修饰符修饰的字段
		Field f = clazz.getDeclaredField("age");
		f.setAccessible(true);//暴力访问
		int a=(Integer)f.get(p);
		System.out.println(a);
		f.set(p, 11);
		System.out.println(f.get(p));
		
	}

	@Test
	//public static int sex = 0;
	public void test3() throws Exception{
		Person p = new Person();
		Class clazz = Class.forName("gw.reflect.Person");
		Field f = clazz.getField("sex");
		System.out.println(f.get(p));
		//f.set(null, 1);
		f.set(p,1);
		//获取字段的值
		System.out.println(f.get(p));
		
	}

参考:   Person.class
public class Person {

	public String name = "gw";
	private int age = 15;
	public static int sex = 0;
	

	public Person() {
		System.out.println("无参构造函数...");
	}

	public Person(String name) {
		System.out.println("一餐构造函数");
	}

	public Person(String name, int age) {
		System.out.println("俩参构造函数");
	}

	private Person(List list) {
		System.out.println("private list构造函数");
	}

	public void aa1() {
		System.out.println("aa1");
	}

	public void aa1(String name, int age) {
		System.out.println(name + ":" + age);
	}
	
	public Class[] aa1(String name,int[] age){
		return new Class[]{String.class};
	}
	
	public void aa1(InputStream in){
		System.out.println(in);
	}
	
	public static void aa1(int num){
		System.out.println(num);
	}
	
	public static void main(String[] args){
		System.out.println("main...");
	}
	
}


















































  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值