gpt4 book ai didi

java - 无法将类 "X"转换为类 "Y",即使 X 扩展了 Y?

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:20:39 27 4
gpt4 key购买 nike

出于某种原因,尝试将一个类 X 转换为另一个类 Y,在第三个类 Z 中抛出ClassCastException。这对我来说似乎是错误的,因为类 X 扩展了另一个类 Y。是否有任何特定原因导致类 X 无法转换为 Y,即使 X 对其进行了扩展?

引用如下代码:

:

public abstract class Y {
/**
* Called when the extension is enabled.
*/
public void onEnable() {
}
}

X:

public class X extends Y {
@Override
public void onEnable() {
// Extension specific code.
}
}

Z:(此代码是 ClassCastException 的来源代码。)

public class Z {
private boolean loadExtension(ExtensionDescription description) {
try {
URLClassLoader loader = new ExtensionClassLoader(new URL[]{description.getFile().toURI().toURL()});
Y y = (Y) loader.loadClass(description.getMain()).newInstance();
} catch (Throwable t) {}
}
}

如果已知 loader.loadClass(description.getMain()).newInstance(); 会创建 X 的新实例,那么为什么要转换为 Y 导致 ClassCastException

最佳答案

为了进一步说明,这里有一个例子:

创建自定义 ClassLoader,例如下面(从 here 复制)

package com.dd;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class CustomClassLoader extends ClassLoader {

/**
* The HashMap where the classes will be cached
*/
private Map<String, Class<?>> classes = new HashMap<String, Class<?>>();

@Override
public String toString() {
return CustomClassLoader.class.getName();
}

@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {

if (classes.containsKey(name)) {
return classes.get(name);
}

byte[] classData;

try {
classData = loadClassData(name);
} catch (IOException e) {
throw new ClassNotFoundException("Class [" + name
+ "] could not be found", e);
}

Class<?> c = defineClass(name, classData, 0, classData.length);
resolveClass(c);
classes.put(name, c);

return c;
}

/**
* Load the class file into byte array
*
* @param name
* The name of the class e.g. com.codeslices.test.TestClass}
* @return The class file as byte array
* @throws IOException
*/
private byte[] loadClassData(String name) throws IOException {
BufferedInputStream in = new BufferedInputStream(
ClassLoader.getSystemResourceAsStream(name.replace(".", "/")
+ ".class"));
ByteArrayOutputStream out = new ByteArrayOutputStream();
int i;

while ((i = in.read()) != -1) {
out.write(i);
}

in.close();
byte[] classData = out.toByteArray();
out.close();

return classData;
}
}

这里是类 Z

package com.dd;

import java.lang.reflect.InvocationTargetException;

public class Z {

public static void main(String[] args) throws ClassNotFoundException,
InstantiationException, IllegalAccessException,
NoSuchMethodException, SecurityException, IllegalArgumentException,
InvocationTargetException {

CustomClassLoader loader = new CustomClassLoader();
Class<?> c1 = loader.findClass("com.dd.X");

System.out.println("Classloader:: "+ X.class.getClassLoader());
System.out.println("Classloader:: "+ loader.findClass("com.dd.X").getClassLoader());

X x = (X)c1.newInstance();
}
}

这是输出:

Classloader:: sun.misc.Launcher$AppClassLoader@781fb069
Classloader:: com.dd.CustomClassLoader
Exception in thread "main" java.lang.ClassCastException: com.dd.X cannot be cast to com.dd.X
at com.dd.Z.main(Z.java:18)

关于java - 无法将类 "X"转换为类 "Y",即使 X 扩展了 Y?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31623155/

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