代码之家  ›  专栏  ›  技术社区  ›  amrezzd

在所有java版本中,是否可以将对象强制转换为具有与其抽象parrent(而不是其parrent)完全相同结构的对象?

  •  0
  • amrezzd  · 技术社区  · 6 年前

    我有一个名为 testlib.jar 它有一个抽象类,如下所示:

    com.test;
    public abstract class AbstractClass {
        public abstract void foo();
    }
    

    一个名为 MyClass 如下所示:

    com.test;
    public class MyClass extends AbstractClass{
        @Override
        public void foo() {
            System.out.println("foo is called in MyClass");
        }
    }
    

    就这样。在我的应用程序中,我有一个抽象类,如下所示:

    com测试;
    公共抽象类抽象类{
    公共抽象void foo();
    }
    

    所以它和 testlib.jar测试库 . 在这里我装了 testlib.jar测试库 文件并实例化 类名 并将其投射到我的应用程序已知的抽象类(第二个类):

    URLClassLoader urlClassLoader = new URLClassLoader(
                new URL[]{new URL("file:\\path\\to\\testlib.jar")});
    Class<AbstractClass> MyClass = (Class<AbstractClass>)urlClassLoader.loadClass("com.test.MyClass");
    Constructor<AbstractClass> c = MyClass.getConstructor();
    AbstractClass myObject = c.newInstance();
    myObject.foo();
    

    输出:

    foo is called in MyClass
    

    注意我在选演员 类名 对于一个不是它真正的父类。

    我有两个问题:

    1-这种方法在所有JVM中都有效吗?

    2-JVM如何在内部处理这个cast操作?

    2 回复  |  直到 6 年前
        1
  •  1
  •   davidxxx    6 年前

    我认为你所做的是违反直觉的,容易出错的。
    你不必用这种方法。相反,提取要在库中共享的API,并在两个方面共享:提供者和客户端。

    另外,你的例子有缺陷,因为你使用 URLClassLoader 依赖父类加载器的构造函数:

    URLClassLoader urlClassLoader = new URLClassLoader(
                new URL[]{new URL("file:\\path\\to\\testlib.jar")});
    

    如文件所述:

    使用 默认委托父类加载器。将在中搜索URL 在第一次搜索后为类和资源指定的顺序 父类加载器。

    这意味着:

    Class<AbstractClass> MyClass = (Class<AbstractClass>)urlClassLoader.loadClass("com.test.MyClass");
    

    加载在当前类路径中定义的类,而不是在JAR中。
    所以这个任务只能作为 AbstractClass 声明的类型还引用当前类路径(而不是JAR)中的类型:

    AbstractClass myObject = c.newInstance();
    

    不要使用默认的父类加载器,您可能会看到 java.lang.ClassCastException :

    URLClassLoader urlClassLoader = new URLClassLoader(
                new URL[]{new URL("file:\\path\\to\\testlib.jar")}, null);
    
        2
  •  0
  •   amrezzd    6 年前

    刚刚在Android 7.1.1上使用 DexClassLoader 而且它很有效,但是在Android 4.2.2上测试时失败了。