我希望能够做到这一点:
public class ConcreteA<B extends AbstractC<D>> {
public D getD() {...}
}
甚至:
public class ConcreteA<B extends AbstractC<?>> {
public <D> D getD() {return cInst.dRelatedMethod();}
}
但似乎我必须这样做:
public class ConcreteA<D, AbstractB extends C<D>> {
public D getD() {...}
}
如果D有自己的类型参数,会变得混乱。有没有办法按照我喜欢的方式进行这种类型的推理? Java Community Process是否在工作中改进了类型推断?
符合条件的答案:
1)存在一种类型推断解决方案,它可以提供我想要的东西,而不需要求助于块#3中的解决方案
2)对任何旨在以适用的方式改进类型推断的JSR的引用
3)驳斥概念的有效性
4)这种JSR不存在的权威声明
答案 0 :(得分:1)
当然!例如,以下代码编译(虽然我不知道为什么有人会需要这样一个奇怪的结构):
public class ConcreteA<B extends AbstractC<D>> {
AbstractC<D> c;
ConcreteA(B b) {
c = b;
}
public D getD() {
return c.getE();
}
}
class AbstractC<E> {
E e;
AbstractC(E e) {
this.e = e;
}
E getE() { return e; };
}
class D {
}
请注意,根据您的班级定义,ConcreteA
,AbstractC
和D
(!)是类,而B
只是模板参数。不要混淆了!
如果您想将D
作为模板参数,则必须在ConcreteA
的类标题中明确指定:
public class ConcreteA<B extends AbstractC<D>, D> {
AbstractC<D> c;
ConcreteA(B b) {
c = b;
}
public D getD() {
return c.getE();
}
}
class AbstractC<E> {
E e;
AbstractC(E e) {
this.e = e;
}
E getE() { return e; };
}
现在,B
和D
(和E
)是模板参数。
答案 1 :(得分:0)
最常见的技术是将你想要的类的Class<T>
作为参数传递给你。
以下是一个示例,但它不会停留在newInstance
。您可以在T
方法内的任何位置正常使用getT
。
public class A<B extends Set<String>> {
final B b;
public A(B b) {
this.b = b;
}
// Hard-coded - not the best.
public String getString () {
return "";
}
// Internally stored so type is retained.
public B getB () {
return b;
}
// Inferred from a parameter passed as a Class<T>.
public <T> T getT(Class<T> clazz) throws InstantiationException, IllegalAccessException {
return clazz.newInstance();
}
}