使用类加载器加载数组

Loading an array with a classloader

我正在尝试 运行 此代码:

public class ClassLoaderTest
{
  public static void main(String[] args) throws Exception
  {
    Object[] obj = new Object[]{};
    String cname = obj.getClass().getName();
    System.out.println(cname);

    ClassLoaderTest.class.getClassLoader().loadClass(cname);
  }
}

但它抛出 ClassNotFoundException。有趣的是,如果我改用这一行:

Class.forName(cname);

它工作得很好。

这是怎么回事?

编辑: 我正在使用 Java 6。println 打印如下:

[Ljava.lang.Object;

完全不一样,

Class.forName return 与给定名称的 class 关联的 Class 对象。

在你的例子中,你给loadClass一个代表class名字的String,而不是直接给它一个class.

此方法确实允许您提供名称,但它必须是 class 的 binary name,而不仅仅是 class 名称。

作为字符串参数提供给 ClassLoader 中的方法的任何 class 名称必须是 Java™ 语言规范定义的二进制名称。

首先,使用 class 加载器尝试加载 java.lang.Object 数组不太可能起作用(因为 java.lang.Object 由默认的 class 加载器加载)。接下来是

给的名字
Object[] obj = new Object[]{};
String cname = obj.getClass().getName();
System.out.println(cname);

[Ljava.lang.Object;。显然,这不是可以通过 ClassLoader - the javadoc says (in part) A class loader is an object that is responsible for loading classes; note it does not say it's responsible for loading arrays. In reflection arrays are handled with java.lang.reflect.Array 解决的 class,它部分表示 Array class 提供静态方法来动态创建并访问 Java 数组。 这似乎是你要找的东西。

查看 source code around the line that the exception is thrown on,它似乎正在尝试构建 class 的文件名,如下所示:

String path = name.replace('.', '/').concat(".class");

鉴于 cname 的值为 [Ljava.lang.Object;,我对找不到 .class 文件并不感到特别惊讶。