我有这样的hirarchy:
class Foo {
...
}
class Bar extends Foo {
...
}
class Baz extends Foo {
...
}
现在我试图在类foo中声明这样的对象:
Class<? extends Foo> anyName;
然后有一些我想要这样做的方法:
anyName = new Foo();
但它不会让我这样做。任何人都可以帮助我吗?
我已经阅读了一些关于泛型和通配符的指南/教程/文档。但我无法解决这个问题。
编辑:修正了大写。对不起,这是一个输入错误。我的原始课程确实如此。
EDIT2:这里的目标是获得Foo的单例实例。
编辑3:我真的很抱歉,现在它应该是正确的!对我感到羞耻:/答案 0 :(得分:3)
Class<Foo>
与Foo
不兼容。
Class<Foo> c = new Foo();
......因为那个原因不能工作。
如果你想要一个Class
类型的对象,通常的做法是使用类名后跟.class
:
Class<Foo> c = Foo.class
你可以像这样处理这个子类:
Class<? extends Foo> c = Bar.class;
但是,如果您对课程有足够的了解并且有理由拥有该类型的变量,那么您可能不会问这个问题。通常我们需要Foo
或Bar
的实例:
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
中声明,可能是一个抽象方法,并在Bar
和Baz
中覆盖,那会更好。
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