我应该向 Proxy.newProxyInstance(...) 提供哪个类加载器?
我已阅读文档,但我仍然不明白应该提供哪个类加载器作为参数。我尝试了一些选项,但这似乎对编译或代理的行为没有影响。有点令人不安的是,我可以传递任何内容作为类加载器参数,包括 null
,并且代码仍然可以正常工作。谁能解释一下这一点,并告诉我如果我为类加载器提供错误的参数,会出现什么样的错误?我应该补充一点,对于 Java 中或一般情况下的类加载器是什么,我并没有一个非常直观的想法。
I have read the documentation, but I still don't understand which classloader I should supply as an argument. I've tried a few options, but this seems to have no effect on compilation or the behavior of the proxy. It is a little unsettling that I can pass anything as the class loader argument, including null
, and the code still works fine. Can anyone explain this, and tell me what kind of errors can arise if I provide a bad argument for the classloader? I should add that I don't really have a strong intuitive idea of what a classloader is, in Java or in general.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
任何类都需要有一个类加载器,因此我们必须在这里给出一个。
重要的部分是这个(在
getProxyClass()
的文档):因此,您可以使用其中一个(或多个)父类加载器定义给定接口的任何类加载器。
如果
null
适用于您的情况,我想您的接口也有null
类加载器(引导加载器) - 那么您使用哪个类加载器应该不重要。如果您必须从您不知道的接口创建代理,只需获取给定的第一个接口的类加载器,并希望您的调用者没有做一些奇怪的事情。为什么需要它?
你可以这样想象:
getProxyClass()
方法为实现所有方法的新类创建(如果尚不存在)一些字节码您的所有接口(每个接口都只是将调用转发到您的InitationHandler
)。defineClass
方法。forName
调用来解析这些接口。我们可以在纯 Java 中以这种方式实现 getProxyClass,而不需要任何 VM 魔法,但是我们需要为其创建一个新的类加载器(将指定的类加载器作为父类),而不是能够重用一个类加载器。现有的一个。
实际上,这个合成类可能没有实际的字节码,因为虚拟机能够在这里使用其内部魔法:-)
Any class needs to have a classloader, thus we have to give one here.
The important part is this (in the documentation for
getProxyClass()
):So, you can use any classloader where one (or more) of its parent classloaders defined the given interfaces.
If
null
works in your case, I suppose your interfaces have also thenull
class loader (the bootstrap loader) - then it should not matter which classloader you used. If you have to create an proxy from interfaces you don't know, simply take the classloader of the first interface given and hope your caller did not do something strange.Why it is needed?
You can imagine it like this:
getProxyClass()
method creates (if it does not exist yet) some bytecode for a new class implementing all the methods of all your interface (each of them simply forwarding the call to yourInvocationHandler
).defineClass
method of the classloader you specified.forName
call to resolve these interfaces.We could have implemented this
getProxyClass
this way in pure Java without any VM magic, but we would need to create a new classloader (with the specified one as a parent) for it instead of being able to reuse an existing one.In reality there might not be an actual bytecode for this synthetic class, since the VM is able to use its internal magic here :-)