gpt4 book ai didi

java - ClassLoader 可以用任何东西替换数组

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:23:10 24 4
gpt4 key购买 nike

当我运行以下 Java 代码时:

ClassLoader c = new ClassLoader() {
@Override
public Class<?> findClass(String name) {
return Object.class;
}
};

Class<?> cc = c.loadClass(Object[][].class.getName());

System.out.println(cc.getName());

即使我将 Object[][].class.getName() 替换为 [[代码中的Ljava.lang.Object。问题是我期待控制台显示 [[Ljava.lang.Object.

实际上,在 JVM specification 中,我可以阅读以下内容:

An array class is created directly by the Java Virtual Machine (§5.3.3), not by a class loader. However, the defining class loader of D is used in the process of creating array class C.

因为 Object[][] 是一个数组类,我假设我的 findClass 不会用参数 [[Ljava.lang. Object 但其元素类型为 java.lang.Object

另外,在“创建数组类”一节中,其实是描述了递归算法:

If the component type is a reference type, the algorithm of this section (§5.3) is applied recursively using class loader L in order to load and thereby create the component type of C.

所以我的问题是:

  • 为什么我会得到这个输出?这是否意味着我必须在我的 ClassLoader 中手动包含这个递归算法,而不是让 JVM 为我做这件事?如果这是它的意思,那么最好的方法是什么?
  • 我是否误解了第一段引文中的“创造”?这是否仅意味着我无法创建运行时数组类,但我仍然可以修补它的加载?

最佳答案

您询问的是 JVM 规范,但您的测试演示了 java.lang.ClassLoader 的行为,这是一个独立类 "invoked by the Java virtual machine to resolve class references" .如果 JVM 正在加载数组类,它将完全绕过类加载器。这可以通过让 JVM 尝试使用自定义类加载器加载类来证明:

Class<?> clazz = Class.forName("[[Lcom.foo.Test;", true, new ClassLoader() {
@Override
public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
System.out.println("Loading " + name);
return super.loadClass(name, resolve);
}
});
System.out.println(clazz);

输出:

Loading com.foo.Testclass [[Lcom.foo.Test;

如您所见,组件类型最初是通过类加载器加载的,但数组类型是隐式加载的。

关于java - ClassLoader 可以用任何东西替换数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41112839/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com