Which ClassLoader should I supply to Proxy.newProxyInstance(…)?

好久不见. 提交于 2020-05-11 04:38:05

问题


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.


回答1:


Any class needs to have a classloader, thus we have to give one here.

The important part is this (in the documentation for getProxyClass()):

All of the interface types must be visible by name through the specified class loader. In other words, for class loader cl and every interface i, the following expression must be true:

Class.forName(i.getName(), false, cl) == i

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 the null 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:

  • The 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 your InvocationHandler).
  • It then passes this bytecode to the defineClass method of the classloader you specified.
  • In this bytecode, all of your interfaces are referenced by name, and the VM now uses the cited 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 :-)



来源:https://stackoverflow.com/questions/5480003/which-classloader-should-i-supply-to-proxy-newproxyinstance

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!