欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java反射机制(Reflection)浅析

程序员文章站 2024-02-27 18:56:03
reflection也就是反射,是java语言的一个重要特征,我们知道,在使用一个类之前,我们往往都已经创建好它了,比如创建一个类文件,然后再写些属性、方法等,也就是这种类...

reflection也就是反射,是java语言的一个重要特征,我们知道,在使用一个类之前,我们往往都已经创建好它了,比如创建一个类文件,然后再写些属性、方法等,也就是这种类是静态的,但反射机制却允许你动态地创建一个类。除了动态地创建一个类外,我们还能动态地获取同类对象的数据,并将这些数据赋给新创建的类,这有点类似克隆复制。在很多时候,我们都需要这种动态创建类的特征,比如在处理一些业务,但这些业务却又稍有区别的时候,往往对应着多个类,在处理的时候,我们就要根据不同的业务处理来调用不同的类,这个时候反射机制就派上用场了。

以下是jdk api中关于软件包java.lang.reflect的描述:

提供类和接口,以获取关于类和对象的反射信息。在安全限制内,反射允许编程访问关于加载类的字段、方法和构造方法的信息,并允许使用反射字段、方法和构造方法对对象上的基本对等项进行操作。

如果必需的 reflectpermission 可用,则 accessibleobject 允许抑制访问检查。

arrays 提供动态创建和访问数组的静态方法。

此包中的类以及 java.lang.class 可以适应以下应用程序的需要:调试程序、解释程序、对象检查程序、类浏览程序,以及服务(比如,object serialization 和 javabean,它们需要访问目标对象(基于其运行时类)的公共成员或给定类声明的成员)。

下面通过两个简单例子来说明反射的用法,首先先创建一个person类:

复制代码 代码如下:

package test;

public class person {

private int age;

private string name = "";

private string[] arr = new string[2];

public person(){}

public person(string name,int age){
this.name = name;
this.age = age;
}

public int getage() {
return age;
}

public void setage(int age) {
this.age = age;
}

public string getname() {
return name;
}

public void setname(string name) {
this.name = name;
}

public string[] getarr() {
return arr;
}

public void setarr(string[] arr) {
this.arr = arr;
}

}

实例1:得到person类的属性及方法信息

复制代码 代码如下:

private static void testsimplereflect(){
string classname = "test.person";
try {
class c = class.forname(classname);
field[] fields = c.getdeclaredfields();
method[] m = c.getdeclaredmethods();
for (field field : fields){
system.out.println(field.getname());
}
for (method method : m){
system.out.println(m.getclass());
}
} catch (classnotfoundexception e) {
e.printstacktrace();
}
}

这种是非常简单的,通过类所在包路径来得到一个类,在实际的工作中,也是使用最多的。

实例2:对象复制

复制代码 代码如下:

@suppresswarnings("unchecked")
public static object copy(object object) throws exception {
// 获得对象类型
class classtype = object.getclass();
system.out.println("" + classtype.getname()); // 通过默认构造方法创建一个新的对象
object objectcopy = classtype.getconstructor(new class[] {})
.newinstance(new object[] {}); // 获得对象的所有属性
field fields[] = classtype.getdeclaredfields();
for (int i = 0; i < fields.length; i++) {
field field = fields[i];
string fieldname = field.getname();
string firstletter = fieldname.substring(0, 1).touppercase(); // 获得和属性对应的getxxx()方法的名字
string getmethodname = "get" + firstletter + fieldname.substring(1); // 获得和属性对应的setxxx()方法的名字
string setmethodname = "set" + firstletter + fieldname.substring(1); // 获得和属性对应的getxxx()方法
method getmethod = classtype.getmethod(getmethodname,
new class[] {}); // 获得和属性对应的setxxx()方法
method setmethod = classtype.getmethod(setmethodname,
new class[] { field.gettype() }); // 调用原对象的getxxx()方法
object value = getmethod.invoke(object, new object[] {});
system.out.println(fieldname + ":" + value); // 调用拷贝对象的setxxx()方法
setmethod.invoke(objectcopy, new object[] { value });
}
return objectcopy;
}

利用反射来实现对象的复制,我们通常不用自己这么干,因为开源系统beanutils已经替我们做好对象拷贝的封装了,我们直接调用它的方法即可,但值得注意的是,beanutils也是基于反射机制来做的封装

下面是一调用:

复制代码 代码如下:

public static void main(string[] args){
person person = new person("tom",22);
string[] strs = new string[]{"a","b"};
person.setarr(strs);
try {
person p = (person)copy(person);
system.out.println(p.getname()+">>"+p.getage());
for (string str : p.getarr()){
system.out.println(str);
}
} catch (exception e) {
e.printstacktrace();
}
//        testsimplereflect();
}