java - 捕获方法参数类型并请求相应的类对象

标签 java generics type-inference

考虑到以下场景

class Base { }
class Extended extends Base {}

我可以轻松地在泛型类的构造函数中请求一个类对象,该类对象是泛型类型的某个子类

class Test<T extends Base> {
  Test(Class<? extends T> test) { }
}

这样我就可以执行以下所有操作

new Test<Base>(Base.class);
new Test<Base>(Extended.class);
new Test<Extended>(Base.class); // This is not allowed by the compiler
new Test<Extended>(Extended.class);

这正是我想要的。但是,我无法弄清楚在使用这样的通用方法时如何实现相同的约束:

<T extends Base> void test(T x, Class<? extends T> test) { }

根据此定义,编译器允许执行以下所有操作:

test(new Base(), Base.class);
test(new Base(), Extended.class);
test(new Extended(), Base.class); // even though Base is not a subclass of Extended
test(new Extended, Extended.class);

我认为这是因为类型推断和 Java 确定

<Base>test(new Extended(), Base.class)

而不是

<Extended>test(new Extended(), Base.class)

但是我如何强制执行后一种推理方法?

感谢您的帮助!

对于 future 的读者:在这个问题的第一个版本中,我将 Base AExtend B。我后来澄清了这个符号。然而,这个符号在答案中使用。

最佳答案

这是计算机科学中的一个问题,因此,can be solved by another level of indirection :

<T extends A, U extends T> void test(T x, Class<U> test) {}

在本例中,我们使用一个类型变量(仅限于 A)来捕获对象参数的类型,并使用第二个类型变量(仅限于第一个)来约束类参数的类型。

如果我写出这个示例并将其提供给 javac (1.6.0_26),它会适时地告诉我:

Test.java:14: cannot find symbol
symbol  : method test(B,java.lang.Class<A>)
location: class Test<T>
        test(b, A.class);
        ^
1 error

正如 @JohnB 在他的评论中暗示的那样,你可以通过写来解决这个问题:

this.<A, A>test(b, A.class);

或者使用原始类型。

关于java - 捕获方法参数类型并请求相应的类对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17296263/

相关文章:

java - 打印机可用性

delphi - 我可以在 Delphi 中对对象的类型过程进行通用约束吗

java - Kotlin-无法推断泛型

java - 如何创建获取泛型参数并返回该类型对象的方法?

f# - F# 中的类型推断

scala - 如何定义具有未绑定(bind)类型参数的成员的案例类?

java - 什么可能导致http ://localhost:9000 not to work testing Java Play in Windows?

java - Apache POI HWPF,替换 .doc 文档中的文本失败

java - Maven多模块子pom版本

防止除以 0 的 typescript 类型