2011-03-29 97 views
9

我已阅读文档,但我仍然不明白应该提供哪个类加载器作为参数。我尝试了几个选项,但这似乎对编译或代理的行为没有影响。我有点不安,我可以通过任何类加载器参数传递任何东西,包括null,并且代码仍然正常工作。任何人都可以解释这一点,并告诉我,如果我为类加载器提供了一个错误的参数,会出现什么样的错误?我应该补充一点,就Java或一般来说,我并没有对类加载器的强大直观概念。我应该向Proxy.newProxyInstance(...)提供哪个ClassLoader?

回答

6

任何类都需要有一个类加载器,因此我们必须在这里给出一个。

的重要组成部分,这是(在the documentation for getProxyClass()):

所有接口类型都必须通过指定的类加载器是按名称可见。换句话说, 的类加载器CL和每一个接口I,下面的表达式必须为真:

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

所以,你可以使用任何类加载器,其中它的父类加载器的一个(或多个)定义的给定接口。

如果null适用于你的情况,我想你的接口也有null类加载器(引导加载程序) - 那么你使用哪个类加载器应该没有关系。如果你必须从你不知道的接口创建一个代理,只需要给出第一个接口的类加载器,并希望你的调用者不会做一些奇怪的事情。

为什么需要它?

你可以把它想象这样的:

  • getProxyClass()方法创建(如果不存在的话)实现所有接口的所有方法的新类的一些字节码(每个人只是转发致电InvocationHandler)。
  • 然后它将这个字节码传递给您指定的类加载器的defineClass方法。
  • 在此字节码中,您的所有接口都按名称引用,现在VM使用引用的forName调用来解析这些接口。

我们可以用纯Java已经实现了这个getProxyClass这种方式没有任何VM魔法,但我们需要创建一个新的类加载器(与指定一个作为家长),因为它不是能够重新使用现有的一。

在现实中可能不存在此合成类实际字节码,因为虚拟机能够在这里使用其内部的魔法:-)

+0

谢谢,我仍然没有什么类加载器做的直觉。你能提一点关于这个吗?我仍然很难理解为什么一个null类加载器可能会工作,如果类加载器负责做任何实质性的事情。也许一个玩具的例子给出了错误的类加载器? – jonderry 2011-03-30 01:24:34

+0

'null'类加载器是“引导类加载器”,加载核心类的类加载器(比如'Class','Object','ClassLoader')。它由VM本地实现,并没有ClassLoader对象。 (它被Class使用。例如,如果你给'null'作为'ClassLoader'参数)。 (例子会晚点来。) – 2011-03-30 11:21:47

相关问题