我已阅读文档,但我仍然不明白应该提供哪个类加载器作为参数。我尝试了一些选项,但这似乎对编译或代理的行为没有影响。有点令人不安的是,我可以传递任何内容作为类加载器参数,包括null
,并且代码仍然可以正常工作。谁能解释一下这一点,并告诉我如果我为类加载器提供错误的参数,会出现什么样的错误?我应该补充一点,对于 Java 中或一般情况下的类加载器是什么,我并没有非常直观的想法。
任何类都需要有一个类加载器,因此我们必须在这里给出一个。
重要的部分是这个(在的文档getProxyClass() http://download.oracle.com/javase/6/docs/api/java/lang/reflect/Proxy.html#getProxyClass%28java.lang.ClassLoader,%20java.lang.Class...%29):
所有接口类型必须通过指定的类加载器按名称可见。换句话说,
对于类加载器 cl 和每个接口 i,以下表达式必须为真:
Class.forName(i.getName(), false, cl) == i
因此,您可以使用任何类加载器,其中一个(或多个)父类加载器定义了给定的接口。
If null
适用于你的情况,我想你的界面也有null
类加载器(引导加载器) - 那么您使用哪个类加载器并不重要。如果您必须从您不知道的接口创建代理,只需获取给定的第一个接口的类加载器,并希望您的调用者没有做一些奇怪的事情。
为什么需要它?
你可以这样想象:
- The
getProxyClass()
方法为一个新类创建(如果尚不存在)一些字节码,该新类实现所有接口的所有方法(每个方法只是将调用转发到您的InvocationHandler
).
- 然后它将这个字节码传递给
defineClass
您指定的类加载器的方法。
- 在此字节码中,所有接口均按名称引用,并且虚拟机现在使用引用的接口
forName
调用来解析这些接口。
我们本来可以实现这个getProxyClass
这种方式在纯 Java 中没有任何 VM 魔法,但我们需要为其创建一个新的类加载器(以指定的类加载器作为父类),而不是能够重用现有的类加载器。
实际上,这个合成类可能没有实际的字节码,因为虚拟机能够在这里使用其内部魔法:-)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)