((我是ByteBuddy的新用户。我使用的是ByteBuddy版本1.10.8和JDK 11,没有模块路径或模块系统的任何其他部分。)
我有一个这样声明的嵌套类:
public static class Frob {
protected Frob() {
super();
}
public String sayHello() {
return "Hello!";
}
}
(其包含的类别为foo.bar.TestExplorations
。]
当我创建一个名为Frob
的动态子类foo.bar.Crap
时,如下所示,一切正常,正如我期望的那样:
final String className = "foo.bar.Crap";
final DynamicType.Unloaded<?> dynamicTypeUnloaded = new ByteBuddy()
.subclass(Frob.class)
.name(className)
.make();
final Class<?> mySubclass = dynamicTypeUnloaded
.load(this.getClass().getClassLoader(), ClassLoadingStrategy.Default.WRAPPER)
.getLoaded();
assertNotNull(mySubclass);
assertEquals(className, mySubclass.getName());
final Object frobSubclass = mySubclass.newInstance();
assertTrue(frobSubclass instanceof Frob);
但是如果我更改Frob
的构造函数以使其为程序包私有,则从最终断言中会出现以下错误:
java.lang.IllegalAccessError: class foo.bar.Crap tried to access method 'void foo.bar.TestExplorations$Frob.<init>()' (foo.bar.Crap is in unnamed module of loader net.bytebuddy.dynamic.loading.ByteArrayClassLoader @5e3d57c7; foo.bar.TestExplorations$Frob is in unnamed module of loader 'app')
由于某种原因,即使Crap
和super()
在同一程序包中,并且Crap
被定义为程序包专用,Frob
的构造函数也无法调用Frob()
。
我有一种责任感是JDK模块系统,尽管我故意(非常非常故意)不使用它。我知道模块系统不喜欢拆分包,这对我来说就像是在继续。是否有构造函数策略或其他机制来解决此问题?
在Java中,只有同一个名称并且由相同的类加载器加载的包(与类相同)才等于另一个包。如果使用WRAPPER
策略,则不能访问任何超类的程序包私有成员。 Byte Buddy不禁止生成,因为在Javac中这样做是合法的,但是您需要使用INJECTION
策略来执行想要确保由相同的类加载器加载类的操作。请注意,它使用内部API,因此从Java 9开始,您宁愿使用ForLookup
类加载策略。