3

在下面的测试用例中,直接字段 t 没有被 CGLIB 截获。那么我可以使用CGLIB吗?

public class Test {

@Test
public void testCGLib() {
    A a = (A) Enhancer.create(A.class, new Class[] {}, new B());
    System.out.println(a.t);
    a.t();
}

public static class A {

    public int t = 0;

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

}

public static class B implements LazyLoader {

    @Override
    public Object loadObject() throws Exception {
        System.out.println("xxx");
        return new A();
    }
}
}
4

1 回答 1

2

不,那是不可能的。字段访问不委托给定义字段的类的某些字节码。它由使用该字段的方法直接加载。(在你的情况下,这是Test#testCGLib。)

cglib 创建一个子类并拦截方法调用。然而,字段不能被覆盖,它们不是多态的,有或没有 cglib。因此,您永远不能拦截字段访问。您只能隐藏子类中的字段。

但是,即使您A#t在检测类中隐藏了该字段:由于 cglib 类在编译时不可见,因此您无法通过检测类型引用该字段。如果检测类A$$cglib有一个字段t,您只能通过

a.getClass().getField("x").get(a)

为了模拟某种动态字段绑定。(基本上,这些方法是动态绑定的,这将导致动态选择正确的字段。

于 2013-11-13T23:00:01.790 回答