小编smi*_*aiw的帖子

如何在运行时将Class <T>转换为类似Class <Textended Foo>的行为?

我有一堂课,看起来像下面这样:

class FooClassAnalyser<T extends Foo> extends ClassAnalyser<T>
Run Code Online (Sandbox Code Playgroud)

(哪里ClassAnalyser是许多具体实现的抽象基类;并且FooClassAnalyser是专门针对T扩展情况的具体实现Foo)。它具有一个如下所示的构造函数:

FooClassAnalyser(Class<T> classToAnalyse)
Run Code Online (Sandbox Code Playgroud)

在另一个类中,我有一个用于ClassAnalyser的静态工厂方法,该方法根据类型调用一个适当的构造函数classToAnalyse

static <U> ClassAnalyser<U> constructClassAnalyser(Class<U> classToAnalyse)
Run Code Online (Sandbox Code Playgroud)

我想要的功能是检查U instanceof Foo,然后构造一个FooClassAnalyser,如果是,则将其返回。

但是,我找不到在Java的类型系统中适合此方法。类型擦除意味着我们不能U直接做任何聪明的事情。但是,我们classToAnalyse作为参数传入的事实使得可以U instanceof Foo通过使用反射来测试是否通过测试:

if (Foo.class.isAssignableFrom(classToAnalyse))
Run Code Online (Sandbox Code Playgroud)

我的问题是,与instanceofJava 不同,这种“通过反射的实例”对Java的类型系统不可见。特别是,将classToAnalyse参数直接传递给FooClassAnalyser的构造函数会失败,并导致类型不匹配,因为Java不知道这classToAnalyse实际上是一个Class<U extends Foo>

到目前为止,我已经找到了最好的解决方案是使用未经检查的铸造,使classToAnalyse一个Class<? extends Foo>(它是实际检查,但Java的不知道它的选中)。至少可以将其作为参数传递给new FooClassAnalyser,并获得FooClassAnalyser<?>返回的对象。但是,问题在于,它不会再转换为ClassAnalyser<U>,因为Java无法识别强制classToAnalyse转换具有不同的泛型绑定,但这并不会改变Class对象仍然是同一对象的事实(因此,仍然是 …

java generics reflection casting dynamic

5
推荐指数
1
解决办法
182
查看次数

在字节码层面,Java 的 Class.getEnumConstants() 如何知道哪些类是枚举类?

Java 反射 API 包含一个方法Class.getEnumConstants(),可以确定一个类是否是一个enum类(null如果它认为该类不是一个enum,则返回),以及它的常量是什么。

我正在开发一个直接生成 JVM 字节码的程序,并试图生成一个枚举类。因此,我需要知道 Java 如何从字节码中识别枚举类,这样getEnumConstants才能正常工作。显然,该类需要扩展Enum,但这显然是不够的(例如,对应于 的字节码public class Example extends Enum<Example> {}不会被识别为enum);类的 JVM 字节码还需要哪些其他功能,以便 Java 的反射 API 将其识别为 Java enum,并能够确定其枚举常量?

java reflection enums jvm-bytecode

2
推荐指数
1
解决办法
202
查看次数

标签 统计

java ×2

reflection ×2

casting ×1

dynamic ×1

enums ×1

generics ×1

jvm-bytecode ×1