您的位置:首页 > 编程语言 > Java开发

Java反射机制,入门初探

2017-08-16 14:13 423 查看

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

一、反射获取类对象

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

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: