Java 泛型:将无界类型转换为有界类型

Java Generics : Convert unbounded types to bounded types

我有两个函数定义为

<T1 extends A> void func1(Class<T1> C);

<T2 extends B> void func2(Class<T2> C);

现在用户将在运行时给出任何类型,根据他给出的我们需要调用 func1 或 func2。我需要类似于

的东西
<T> void func(Class<T> C){
    // check if Class C extends A, then call func1 else call func2
    if (T extends A){
        func1(C);
    }
    else{
        func2(C);
    }
}

我是 Java 泛型的新手,我想知道这是否可行?如果可能,我应该怎么做?

不是,至少不是泛型。

泛型几乎完全是编译器想象力的产物。

在编译时,泛型信息就在那里,但只有你的眼睛能看到那么多。如果我写:

class Example<T> {
    void foo(T in) {}
}

然后你的眼球无法判断在任何给定的 foo 方法调用中 T 将是什么,只看这段代码。所以编译器也不知道,因此在编译时你不知道 T 是什么。您不能编写这样的代码:“给我任何 T,也许以 java.lang.Class 实例的形式”。

在运行时此信息不再存在 - 这称为擦除。

有一些泛型在运行时可用 - 基本上,只要泛型出现在签名中(即字段类型,extendsimplements 行中提到的任何类型, 任何方法 return 类型, 任何方法参数类型) - 你仍然可以在运行时得到它,但你得到的只是代码中字面上写的内容。

因此,一旦您提出以下问题:我能否以某种方式将 jlClassInstance.isAssignableFrominstanceof 等运行时概念与泛型绑定混合使用,答案很简单:不。不可能。 - 但这就是你要问的。

我确实提到,PROVIDED 所讨论的方法在其源代码中明确列出了类型,嗯,现在它是签名的一部分,你理论上可以在运行时查询这个。所以如果你有:

    <T extends Number> void func1(Class<T> c) { ... }
    <T extends List<?>> void func2(Class<T> c) { ... }

然后可以在运行时检索,经过大量的箍和棘手的代码后,Number.classList.class。但是,你不应该这样做,这是泛型滥用。如果有人写道:

    class Foo<Y> {
        <T extends Y> void func3(Class<T> c) { ... }
    }

因为这样可以很好地编译,而你的计划是:我将使用反射来检查绑定的实际类型并使用它在运行时分派一些东西 - 在这里行不通。您在运行时所能知道的就是名称是 'T',它的下限是 'Y',而 'Y' 是封闭类型的无限类型参数。

考虑这个问题:为什么在 Java 中提供泛型?

提供泛型是为了在编译时而不是运行时检测更多类型转换错误。

现在让我们回到你的问题:

Now user will give any type at runtime, based on what he gives we need to call either func1 or func2.

这与 Java 中提供的泛型完全相反,因为您想在运行时提供任何类型,我建议您以用户无法在运行时将任何类型传递给的方式更改您的设计您的方法,此设计容易出错,这些错误将在运行时检测到!