可以做&#34; Class <! - ?扩展foo - > foo&#34;?

时间:2017-05-24 07:50:34

标签: java generics bounded-wildcard

我有这样的hirarchy:

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

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

Class<? extends Foo> anyName;

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

anyName = new Foo();

但它不会让我这样做。任何人都可以帮助我吗?

我已经阅读了一些关于泛型和通配符的指南/教程/文档。但我无法解决这个问题。

编辑:修正了大写。对不起,这是一个输入错误。我的原始课程确实如此。

EDIT2:这里的目标是获得Foo的单例实例。

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

3 个答案:

答案 0 :(得分: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都是&#34;代码气味&#34; - 不一定是错的,但有证据表明可以更好地设计某些东西。

如果您的方法在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编程中最重要的概念之一。

答案 1 :(得分:2)

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

您想要实现的是获取一个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;
}

答案 2 :(得分:0)

您可以使用反射API通过Class<? extends Foo> anyName

创建anyName.getDeclaredConstructor().newInstance()所有内容的新实例

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