即使X扩展了Y,也无法将类“ X”转换为类“ Y”吗?

hmc_jake

出于某种原因,尝试在第三类中将一个类X转换为另一个YZ会引发ClassCastException我看到这是错误的,因为该类X扩展了另一个类Y有什么特殊的原因导致即使扩展X也不能转换为YX

请参阅以下代码以供参考:

Y

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

青蛙

为了进一步说明,这是一个示例:

创建一个Custom ClassLoader,例如下面(从此处复制

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)

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章