Java反射机制,入门初探

反射,很麻烦,但是很强大,不然谁用啊。

一、反射获取类对象

类对象概念: 所有的类,都存在一个类对象,这个类对象用于提供一类层面的信息,比如有几种构造方法, 有多少属性,有哪些普通方法。

Java中获取类对象有3种方式
1. Class.forName
2. Hero.class
3. new Hero().getClass()

在一个JVM中,一种类,只会有一个类对象存在。所以以上三种方式取出来的类对象,都是一样的。

String className = "User";// 这是类的名称
try {
  	Class pClass1=Class.forName(className);
    	Class pClass2=User.class;
     	Class pClass3=new User().getClass();
     	System.out.println(pClass1==pClass2);//true
   	System.out.println(pClass1==pClass3);//true
} catch (ClassNotFoundException e) {
  	// TODO Auto-generated catch block
    	e.printStackTrace();
}
public class User {
	private int id;
	private int age;

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

如上这就是反射的使用,获取类对象。

二、使用反射创建对象实例

try {
	String ClassName = "User";//声明类对象名
	Class userClass = Class.forName(ClassName);//创建类对象
	Constructor<Object> userConstr = userClass.getConstructor();//通过类对象获取构造器
	User u1 = (User)userConstr.newInstance();//再通过构造器实例化
	u1.setAge(19);
	System.out.println(u1);//User@6d06d69c
	
} catch (Exception e) {
	// TODO: handle exception
	e.printStackTrace();
}

反射机制是在程序运行时操作的,即不是在编译阶段。因为是通过一个对象名获取该对象,所以可以使用配置文件来设置反射操作的对象。
源代码不需要发生任何变化,只需要修改配置文件,就可以导致程序的逻辑发生变化, 这是一种基于配置的编程思想。
Spring框架中的IOC和DI的底层就是基于这样的机制实现的。

三、反射机制 访问对象属性、调用对象方法
主要使用getField和getDeclaredField方法。二者的区别:
这两个方法都是用于获取字段
getField 只能获取public的,包括从父类继承来的字段。
getDeclaredField 可以获取本类所有的字段,包括private的,但是不能获取继承来的字段。
 (注: 这里只能获取到private的字段,但并不能访问该private字段的值,除非加上setAccessible(true))
	User u1 =new User();
	//使用传统方式修改name的值为gareen
        u1.setAge= 18;
        try {
            //获取类User的age字段,//需要先修改User中age字段权限修饰符
            Field f1= h.getClass().getDeclaredField("age");
            //修改这个字段的值
            f1.set(h, "teemo");
            //打印被修改后的值
            System.out.println(h.name);
             
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
调用方法:
public class Qiyu extends User{
	public Qiyu() {
		System.out.println("构造方法QIYU");
	}
	static {
		System.out.println("静态代码块QIYU");
	}
	public void showName() {
		System.out.println("my name is QIYU");
	}
}
在try-catche块中调用方法:
//根据反射,获取User1,并且给User1的age字段赋值
	Class User1Class = Class.forName("User.Qiyu");
	Constructor User1Constructor = User1Class.getConstructor();
	Object User1 = User1Constructor.newInstance();
	Field User1AgeField = User1Class.getField("age");
       	User1AgeField.set(User1, 18);
 
      	//根据反射,获取Qiyu中的showName方法
	Method attackUserMethod = User1Class.getMethod("showName", User.class);
	attackUserMethod.invoke(User1);
四、总结一下作用
通常来说,需要在学习了Spring 的依赖注入,反转控制之后,才会对反射有更好的理解
使用反射方式,首先准备一个配置文件,就叫做spring.txt吧, 放在src目录下。 里面存放的是类的名称,和要调用的方法名。
在测试类Test中,首先取出类名称和方法名,然后通过反射去调用这个方法。

当需要从调用第一个业务方法,切换到调用第二个业务方法的时候,不需要修改一行代码,也不需要重新编译,只需要修改配置文件spring.txt,再运行即可。

这也是Spring框架的最基本的原理,只是它做的更丰富,安全,健壮。

思路和总结参考 http://how2j.cn/k/reflection/reflection-class/108.html?p=13011



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值