【问题标题】:Java & Type Erasure - How to generify MyClass.class from the string "MyClass"Java & Type Erasure - 如何从字符串“MyClass”生成 MyClass.class
【发布时间】:2021-07-27 03:18:06
【问题描述】:

所以我有一个参数化处理程序类型,该类型是MessageBase 的子类。

public class ResponseHandler<T extends MessageBase> {

    private final T message;

    private ResponseHandler(final Class<T> clazz) {
        this.message = get(clazz);
    }

    public static <T extends MessageBase> ResponseHandler<T> of(Class<T> clazz) {
        return new ResponseHandler<>(clazz);
    }

    private T get(Class<T> clazz) {
        ...
    }
}

我还有DerivedMessage 类的子集,例如DerivedMessage1DerivedMessage2,它们都扩展了MessageBase。我希望能够基于这样的类名字符串创建正确的ResponseHandler

// defined some String s;
if (s == "com.package.DerivedMessage1") {
    ResponseHandler<DerivedMessage1> h1 = ResponseHandler.of(DerivedMessage1.class);
    // do something with h1
} else if (s == "com.package.DerivedMessage2") {
    ResponseHandler<DerivedMessage2> h2 = ResponseHandler.of(DerivedMessage2.class);
    // do something with h2
}

但我想知道是否有一种方法可以对所有派生自MessageBaseDerivedMessage 类进行通用处理。我还没有找到从“com.package.DerivedMessage1”之类的字符串执行DerivedMessage1.class 的方法。我试过Class.forName(string),但它返回一个奇怪的capture ? 类型,让我感到困惑。有没有办法做到这一点,还是我必须坚持 if 语句?

【问题讨论】:

  • 在检索到“正确”的 ResponseHandler 实例后你想做什么?泛型类型只对编译器有意义,在运行时所有 T 都将是 Object(或者在这种情况下至少是 MessageBase)。那么 ResponseHandler 有什么问题,你不能用它完成什么?
  • 你不能使用演员表。 Class clazz = (Class) Class.forName(s); ResponseHandler h = ResponseHandler.of(clazz);
  • 首先,停止将字符串与== 进行比较,那么“捕获”就没有什么奇怪的了。最后一点是“基于类的字符串”,为什么?为什么不能基于Class

标签: java class generics type-erasure


【解决方案1】:

你可以使用getCanonicalName()

例如: DerivedMessage1.class.getCanonicalName() 返回"com.package.DerivedMessage1"

所以条件变成了

if (DerivedMessage1.class. getCanonicalName().equals(s))) {
    ResponseHandler<DerivedMessage1> h1 = ResponseHandler.of(DerivedMessage1.class);
    // do something with h1
}

【讨论】:

  • 什么?不,这不是我要问的。我正在努力做到这一点,这样我就不必为每个 DerivedMessage 类设置一个 if 条件。接受类名字符串并返回正确的ResponseHandler
  • 那么你可以像这样使用反射ResponseHandler.of(Class.forName(s).getConstructor().getNewInstance());
  • 这给了我期望?但得到capture ?的错误。或类似的东西。 forName 有一些它不喜欢的地方。
  • Class.forName(s).getConstructor().getNewInstance() 它返回作为参数s 提供的类的实例,因此您不需要处理cature ?,它跟踪给定类的元信息,如构造、属性、方法
  • 如何从MyClass 的实例转到MyClass.class?这就是我遇到的问题。似乎一般不可能做到这一点。
猜你喜欢
  • 2016-03-31
  • 2014-10-23
  • 1970-01-01
  • 2012-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多