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

java反射机制实战示例分享

程序员文章站 2024-02-23 16:22:40
首先,我们来认识几个类。 class(java.lang.class) class对象是一个特殊对象,每一个类都有一个class对象,用来创建该类的“常规”对象。可以通...

首先,我们来认识几个类。

class(java.lang.class)

class对象是一个特殊对象,每一个类都有一个class对象,用来创建该类的“常规”对象。可以通过对象的getclass()方法获取。

比如我们运行这一行代码:

复制代码 代码如下:

system.out.println("测试".getclass().tostring());

得到的结果就是:

复制代码 代码如下:

class java.lang.string

field(java.lang.reflect.field)

这个类表示一个字段,可以使用这个字段来访问类

下面,我们来创建测试类:

复制代码 代码如下:

class book {
    public string title;
    public int length = 0;
    public arraylist<page> pages = null;

    @override
    public string tostring() {
        string sb = "book:\n";
        sb += "title="+title+"\n";
        sb += "length=" + length + "\n";
        sb += "pages=" + pages + "\n";
        if (pages != null) {
            for (page page : pages) {
                sb += page.tostring();
            }
        }
        return sb.tostring();
    }
}

class page {
    @override
    public string tostring() {
        return "page\n";
    }
}

调用以下方法来测试上面的类:

复制代码 代码如下:

book book = new book();
system.out.println(book);

它的结果是这样:

复制代码 代码如下:

book:
title=null
length=0
pages=null

这是book对象的初始状态

我们下面通过反射机制,获取book对象中的length字段并进行修改,查看结果:

复制代码 代码如下:

book book = new book();
class<?> aclass = book.getclass();
field field = aclass.getfield("length");
field.setint(book, 9);
system.out.println(book);

可以看到运行结果是:

复制代码 代码如下:

book:
title=null
length=9
pages=null


可以看出,length字段的值已经被修改了。

上面修改的是int型的简单字段,事实上像title字段这样的对象字段也是可以修改的,下面是示例:

复制代码 代码如下:

book book = new book();
class<?> aclass = book.getclass();
field[] fields = aclass.getfields();
for (field field : fields) {
    field.setaccessible(true);
    if(field.gettype().equals(string.class)){
        field.set(book, "格林童话");
    }else if(field.gettype().equals(int.class)){
        field.set(book, 199);
    }
}
system.out.println(book);

上面的代码输出结果是:

复制代码 代码如下:

book:
title=格林童话
length=199
pages=null

事实上,是将所有string类型的字段都修改成“格林童话”,将所有int类型字段都修改成199 。我们甚至根本不知道这个字段代表什么意思。

下面,我们对pages这个字段进行修改。这个字段是个arraylist,我们将创建一个arraylist对象,并向其中插入一个对象。

复制代码 代码如下:

book book = new book();
class<?> aclass = book.getclass();
field[] fields = aclass.getfields();
for (field field : fields) {
    field.setaccessible(true);
    if(field.gettype().equals(arraylist.class)){
        string genric = field.getgenerictype().tostring();
        string genricclass = genric.substring(
                            genric.indexof('<') + 1,
                            genric.indexof('>'));
        class<?> entityclass = class.forname(genricclass);
        object obj = entityclass.newinstance();
        arraylist list = new arraylist();
        list.add(obj);
        field.set(book, list);
        }
    }
system.out.println(book);

输出结果如下:

复制代码 代码如下:

book:
title=null
length=0
pages=[page
]
page

可以看出,尽管我们根本没有直接使用page类,但还是创建出了一个page对象。

page对象的创建语句在:entityclass.newinstance()这一句。newinstance语句是class对象的重要方法,用来创建这个类对应的对象。当然,需要类的构造方法支持。另外,通过gengenerictype方法,我们可以获取到字段的类型修饰符。放在这里,获取到的就是arraylist<page>。有了这一个字符串,我们就可以通过类加载器class.forname来加载page类并创建一个page对象了。