【发布时间】:2013-06-16 23:05:44
【问题描述】:
我正在尝试使 API 尽可能用户友好。
让我们来:
class B extends A {}
class A {
A setX(){ ...; return this; }
}
现在这个
B b = new B().setX();
无效,必须强制转换:
B b = (B) new B().setX();
有没有办法在A 中使用泛型来让编译器知道“this”类型并接受第一种方式——不进行强制转换,也不在使用的地方传递类型参数? (即不是new B<B>().setX(),那太丑了。)
我知道为什么在这种情况下 Java 需要重新输入。请不要回答解释 setX() 返回 A。我知道。
我在问泛型是否可以解决这个问题。
对于那些仍然想告诉我“这就是静态类型的工作原理”和“即使是泛型也无济于事”的人,请考虑以下有效的 Java 代码:
Map<String, String> map = new HashMap(){{ put( "foo", new RuntimeException() );
String foo = map.get("foo"); // ClassCastException!!
因此您可以看到,泛型确实允许您在代码中不出现实际类型转换的情况下获得 CCE。
这就是为什么我希望泛型允许摆脱显式类型转换的原因。
另外,IIRC C++ allows that.
【问题讨论】:
-
这里的问题是子类不能持有父类声明的对象引用,这必然需要向下转换。即使是泛型也无法帮助您。
-
他们有可能。它本身不需要向下转换。
-
好吧,你可以说
<T extends A> T setX() { return (T)this; },但请注意,你在这里是低调的。 -
泛型不会抑制这一点。
-
Typescript 在这里有所需的概念 (typescriptlang.org/docs/handbook/…),所以这个问题在书面上是有效的。