可以做"Class<? extends foo> foo"吗?



我有这样的毛茸茸:

class Foo {
...
}
class Bar extends Foo {
...
}
class Baz extends Foo {
...
}

现在我正在尝试在类 foo 中声明这样的对象:

Class<? extends Foo> anyName;

然后有一些方法我想这样做:

anyName = new Foo();

但它不会让我这样做。谁能帮我?

我已经阅读了几个关于泛型和通配符的指南/教程/文档。但是我还没有找到解决这个问题的方法。

编辑:修复了大写。抱歉,这是一个打字错误。我原来的班级确实是这样的。

编辑2:这里的目标是获得Foo的单例实例。

编辑3:真的很抱歉,现在应该是正确的!为我感到羞耻:/

Class<Foo>

Foo的类型不兼容。

Class<Foo> c = new Foo();

。由于这个原因而不起作用。

如果你想要一个类型为Class的对象,通常的方法是使用类名后跟.class

Class<Foo> c = Foo.class

你可以像这样做这个句柄子类:

Class<? extends Foo> c = Bar.class;

但是,如果您足够了解类,并且有理由拥有这种类型的变量,则可能不会问这个问题。通常我们想要一个FooBar的实例

Foo a = new Foo();
Bar b = new Bar();
Foo c = new Bar(); // type compatible because of inheritance

您提到要调用方法和/或强制转换变量。

你可以做:

Foo a = ...;
if(a instanceof Bar) {
Bar b = (Bar) a;
b.someMethodOfBar();
}

然而,铸造和instanceof都是"代码气味"——不一定是错误的,而是证明某些东西可以设计得更好。

如果你的方法在Foo中声明会更好,也许是一个抽象方法,并在BarBaz中被覆盖。

Foo a = ...;
a.someMethod();   // if it's a Bar, this is Bar.someMethod()
// if it's a Baz, this is Baz.someMethod()

这称为多态性,是OO编程中最重要的概念之一。

我不确定你想从这里得到什么,但我的建议太长了,无法发表评论。

你想要实现的是获取一个变量,它是Foo的实例,这样你就可以anyName = new Foo()执行此操作。但是您也希望能够做到这一点anyName = new Bar();或这种anyName = new Baz();

如果我就在这里,你不需要使用泛型。相反,您只需按如下方式定义anyName

Foo anyName;

根据评论进行更新

您无法获取您不知道的对象的实例。我会使用这种方法之一:

您可以将变量转换为所需的时间。例如:

((Bar) anyName).someBarMethod();

或者,可以创建一个泛型方法来获取所需的类型。当您在投射时需要一些灵活性时,这很有用:

public <T extends Foo> T getFoo(Class<T> type){
return (T) anyName;
}

可以使用反射 API 创建任何Class<? extends Foo> anyName的新实例,方法是使用anyName.getDeclaredConstructor().newInstance()

下面是一个详细示例:https://docs.oracle.com/javase/tutorial/reflect/member/ctorInstance.html

最新更新