【问题标题】:Loading an array with a classloader使用类加载器加载数组
【发布时间】:2015-08-05 01:21:20
【问题描述】:

我正在尝试运行此代码:

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;

【问题讨论】:

  • 我猜你是出于好奇而问的,因为在 java 数组中,“类”是由 vm 生成的,所以加载它们是没有意义的。 (您将加载组件类,然后创建一个数组,然后 vm 将创建数组类)
  • 一个数组类型确实是一个类;并且Class.forName() javadoc 允许它。

标签: java class classloader loader


【解决方案1】:

它们根本不一样,

Class.forName 返回与给定名称的类关联的 Class 对象。

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

这个方法允许你给一个名字,但是它必须是类的binary name,而不仅仅是类名。

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

【讨论】:

    【解决方案2】:

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

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

    [Ljava.lang.Object;。显然,这不是一个可以通过 ClassLoader 解析的类——javadoc 说(部分)类加载器是一个负责加载类的对象;请注意,它并没有说它负责加载数组。在反射数组中,由java.lang.reflect.Array 处理,这在某种程度上说,Array 类提供了动态创建和访问 Java 数组的静态方法。这似乎是您正在寻找的。

    【讨论】:

      【解决方案3】:

      查看source code around the line that the exception is thrown on,看起来它正在尝试像这样构建类的文件名:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-12-30
        相关资源
        最近更新 更多