【问题标题】:Casting a class using reflection in java在java中使用反射铸造一个类
【发布时间】:2013-06-26 13:33:32
【问题描述】:

我有以下课程。

abstract class A{}

class B extends A{}

class C extends A{}

我需要创建一个像这样的对象

A a = new B();

我在运行时得到子类的类名。所以,我需要使用反射来创建一个对象。

我已经做到了。

Class<?> klass = Class.forName(className);

现在我无法将此类转换为子类。

我要实现

A a = klass.newInstance(); // returns Object

我希望将对象转换为子类(BC,取决于运行时)

我该怎么做?

【问题讨论】:

  • A a = (A)klass.newInstance(); 有什么问题?
  • @AleksG 我需要访问子类中的函数。
  • switch (name) { case "B": return new B(); case "C": return new C(); default: throw new SomeException(); } 有什么问题? /Class.newInstance 有什么问题?很多。如果您正在使用Constructor.newInstance,最好先使用asSubclass
  • 因为无论如何你都在使用反射,所以你实际上不必强制它们来使用子类中的函数......
  • @rgksugan 反射没有什么干净的。

标签: java reflection casting


【解决方案1】:

你可以使用泛型来声明

Class<? extends A> klass;

那你就可以写了

A a = klass.newInstance();

但是,由于Class.forName 没有关于您的类的类型信息,也没有声明类型推断,您将收到“未经检查的强制转换”警告。这种方法并不比将第二行的结果向下转换为A 更安全。

【讨论】:

  • 不兼容的类型。找到:类>
  • 是的。您需要在右侧进行显式转换。无论如何,它并没有给你太多的好处:你不能让一段固有的类型不安全的代码类型安全。
  • A a = Class.forName( … ).asSubclass(A.class).newInstance(); 甚至可以在没有未经检查的类型转换的情况下工作,并且是类型安全的。
【解决方案2】:

我希望将对象转换为子类(B 或 C,在运行时决定)

这没有任何意义。强制转换主要是一种编译时操作,最终得到适当类型的表达式。然后在执行时对其进行验证。

如果你真的想实现A类型的变量,那么你只需要转换为A

A a = (A) klass.newInstance();

【讨论】:

    【解决方案3】:

    拥有klass 类型为Class&lt;T&gt; 的对象,您可以调用Class.cast() 方法来转换为T 类型使用

    klass.cast(object)
    

    例如,您有 B 类型的 a,您将 a 转换为类型 B 在运行时加载。

    Class<?> klass = Class.forName("B");
    klass.cast(a);
    

    【讨论】:

      【解决方案4】:

      要跟进 cmets,您可以使用以下任一方法创建类的实例

      Class klass = Class.forName(className);
      A a = (A)klass.newInstance();
      

      Class<? extends A> klass = Class.forName(className);
      A a = klass.newInstance();
      

      然后你可以调用它的方法:

      klass.getMethod(methodName, null).invoke();
      

      或者,如果方法接受参数(例如 intString

      int param1 = ...;
      String param2 = ...;
      klass.getMethod(a, new Class[] { Integer.class, String.class }).invoke(param1, param2);
      

      当然,您需要捕获适当的异常。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-10-21
        • 2011-02-07
        • 1970-01-01
        • 1970-01-01
        • 2011-07-28
        • 1970-01-01
        • 2015-05-21
        相关资源
        最近更新 更多