实例化并应用具有未知泛型类型的泛型方法-Java

实例化并应用具有未知泛型类型的泛型方法-Java,java,generics,reflection,Java,Generics,Reflection,我需要实例化一个具有未知泛型类型的对象,然后对其应用泛型方法。我的立场如下: public static void main(String[] args) { BarIf bar = newRandomBarImpl(); Foo foo1 = newFooBar(bar.getClass()); // warning Foo<?> foo2 = newFooBar(bar.getClass()); // error Foo<? extends

我需要实例化一个具有未知泛型类型的对象,然后对其应用泛型方法。我的立场如下:

public static void main(String[] args)
{
    BarIf bar = newRandomBarImpl();

    Foo foo1 = newFooBar(bar.getClass()); // warning
    Foo<?> foo2 = newFooBar(bar.getClass()); // error
    Foo<? extends BarIf> foo3 = newFooBar(bar.getClass()); // error

    foo1.doSomething(bar); // warning
    foo2.doSomething(bar); // error
    foo3.doSomething(bar); // error
}

static <T extends FooIf<S>, S extends BarIf> T newFooBar(Class<S> barClass){}

static <T extends BarIf> T newRandomBarImpl(){}

interface FooIf<T extends BarIf>
{
    public void doSomething(T t);
}

interface BarIf{}

class Foo<T extends BarIf> implements FooIf<T>
{
    public void doSomething(T t){}
}
publicstaticvoidmain(字符串[]args)
{
BarIf bar=newRandomBarImpl();
Foo foo1=newFooBar(bar.getClass());//警告
Foo foo2=newFooBar(bar.getClass());//错误

Foo首先,声明如下

static <T extends BarIf> T newRandomBarImpl(){}
没有得到编译器警告。显然,这是行不通的。
newRandomBarImpl()
ArbiraryTypeExtendingBarif
一无所知。方法名称表明您实际上想要表达
newRandomBarImpl()
可以返回任意实现的
BarIf
,但这是不必要的泛型用法

BarIf newRandomBarImpl(){}
已经表示此方法可以返回任意子类型的
BarIf
。事实上,由于
BarIf
是一个抽象类型,因此此方法必须返回
BarIf
的子类型,并且没有指定它将是哪个子类型

这同样适用于该声明

static <T extends FooIf<S>, S extends BarIf> T newFooBar(Class<S> barClass){}
因为该方法决定了
FooIf
的哪个实现将返回,而不是调用方


关于处理
FooIf
的其他尝试,您不能使用通配符参数化的类型以这种方式工作,也不能使用反射来修复它。但您可以使用类型参数编写泛型代码:

public static void main(String[] args)
{
    BarIf bar = newRandomBarImpl();
    performTheAction(bar.getClass(), bar);
}
static <T extends BarIf> void performTheAction(Class<T> cl, BarIf obj) {
    FooIf<T> foo=newFooBar(cl);
    foo.doSomething(cl.cast(obj));
}
static <S extends BarIf> FooIf<S> newFooBar(Class<S> barClass){}
static BarIf newRandomBarImpl(){}

interface FooIf<T extends BarIf> {
    public void doSomething(T t);
}
interface BarIf{}
请注意,当您想要使用界面中未指定的实际实现类型
Foo
的方法时,您必须将
FooIf
转换为
Foo
。您可以将
FooIf
转换为
FooIf
,而无需发出警告,因为如果
Foo实现了FooIf
,则泛型类型转换是正确的


但是,它可能会在运行时失败,因为方法
newFooBar
不需要返回
Foo
的实例,而不是
FooIf
的任何其他实现。这就是为什么显式类型转换是唯一正确的解决方案,因为它记录了对对象的实际运行时类型所做的假设。All其他尝试至少会在某个地方生成一个编译器警告。

为什么不将变量声明为
FooIf
,而不是
Foo
?因为我想应用那些可能不会在FooIf中声明,但只能在Foo中声明的方法。这就是为什么我首先使用泛型方法的原因。为什么没有使用类型转换?我如何才能转换到
Foo
?我成功地让它工作了。谢谢。我想我的泛型搞乱了。
static <S extends BarIf> FooIf<S> newFooBar(Class<S> barClass){}
public static void main(String[] args)
{
    BarIf bar = newRandomBarImpl();
    performTheAction(bar.getClass(), bar);
}
static <T extends BarIf> void performTheAction(Class<T> cl, BarIf obj) {
    FooIf<T> foo=newFooBar(cl);
    foo.doSomething(cl.cast(obj));
}
static <S extends BarIf> FooIf<S> newFooBar(Class<S> barClass){}
static BarIf newRandomBarImpl(){}

interface FooIf<T extends BarIf> {
    public void doSomething(T t);
}
interface BarIf{}
BarIf bar = newRandomBarImpl();
FooIf<BarIf> foo=newFooBar(BarIf.class);
foo.doSomething(bar);