我有一个参数化类型A<T extends B>
和另一个C<T2 extends A>
。
是否可以(静态)T
从内部引用子类,C
而不必添加T
为第二个类型参数C
?目标是添加一个C
返回类型的方法T
。
我想写的:
class A<T extends B> {
}
class C<T2 extends A<T>> {
T myMethod() {
}
}
我有一个参数化类型A<T extends B>
和另一个C<T2 extends A>
。
是否可以(静态)T
从内部引用子类,C
而不必添加T
为第二个类型参数C
?目标是添加一个C
返回类型的方法T
。
我想写的:
class A<T extends B> {
}
class C<T2 extends A<T>> {
T myMethod() {
}
}
就目前情况而言,您A
在定义中使用了原始类型C
:
C<T2 extends A>
这是个坏主意,并且您不能期望在此上下文中获得有关类型参数的信息,因为您没有指定任何参数。没有T
找到。
在您的定义中A
,类型T
只是一个参数。除非您使用具有A
特定类的特定作为参数,T
否则不会引用任何内容。当你定义 时C
,你必须说明A
你正在扩展什么风格,或者换句话说,指定一个真实的类型。
你所做的有点像询问x
in 的值是什么f(x) = x+1
。在您f
使用某些特定参数调用之前,x
它只是一个标签。
我认为答案是肯定的,你可以,间接地。
由于类型擦除,我认为您不能直接执行此操作。正如其他人所提到的,您必须添加另一个参数、类型参数或嵌套类。
您可以使用泛型函数、类调用者的帮助和基类的帮助的组合间接地做到这一点:
class B
{
}
class B2 extends B // B2 is Just an example of a concrete type T
{
}
class A<T extends B> {
T t;
T getT()
{
return t;
}
}
class C<T2 extends A<?>> {
T2 t2;
T2 getT2()
{
return t2;
}
<X> X getValWithInnerType(A<? extends X> x)
{
return x.getT();
}
}
public class Example {
public static void main(String[] args) {
C<A<B2>> c1 = new C<>();
B2 inner = c1.getValWithInnerType(c1.getT2());
}
}
如果你愿意得到你想要的类型,但不一定直接来自 C 类,你也可以使用组合做一些更简单的事情:
class B
{
}
class B2 extends B
{
}
class A<T extends B> {
T t;
T getT()
{
return t;
}
}
class C<T2 extends A<?>> {
T2 t2;
T2 getT2()
{
return t2;
}
}
public class Example {
public static void main(String[] args) {
C<A<B2>> c1 = new C<>();
B2 inner = c1.getT2().getT();
}
}
最后,如果获得确切的派生类型 T 不是那么重要,您可以只使用一个返回类型 B 的函数:
class B
{
}
class B2 extends B
{
}
class A<T extends B> {
T t;
T getT()
{
return t;
}
}
class C<T2 extends A<? extends B>> {
T2 t2;
B getT2()
{
return t2.getT();
}
}
规范的第 4.4 节说
A type variable is introduced by the declaration of a type parameter of
a generic class, interface, method, or constructor.
T
右边出现的是extends
类型变量,而不是类型参数。如果要将其用作变量,则它需要是范围内的参数。
您可以T
像这样添加为参数:
class A<T extends B> {
...
}
class C<T, T2 extends A<T>> {
T myMethod() {
...
}
}
但这是你的问题试图避免的。另一种方法是创建C
一个内部类:
class A<T extends B> {
class C<T2 extends A<T>> {
T myMethod() {
...
}
}
...
}