1

我有一个参数化类型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() {

    }
}
4

3 回答 3

2

就目前情况而言,您A在定义中使用了原始类型C

C<T2 extends A>

这是个坏主意,并且您不能期望在此上下文中获得有关类型参数的信息,因为您没有指定任何参数。没有T找到。

在您的定义中A,类型T只是一个参数。除非您使用具有A特定类的特定作为参数,T否则不会引用任何内容。当你定义 时C,你必须说明A你正在扩展什么风格,或者换句话说,指定一个真实的类型。

你所做的有点像询问xin 的值是什么f(x) = x+1。在您f使用某些特定参数调用之前,x它只是一个标签。

于 2014-10-07T10:45:48.580 回答
0

我认为答案是肯定的,你可以,间接地。

由于类型擦除,我认为您不能直接执行此操作。正如其他人所提到的,您必须添加另一个参数、类型参数或嵌套类。

您可以使用泛型函数、类调用者的帮助和基类的帮助的组合间接地做到这一点:

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();
     }


}
于 2014-10-07T21:12:10.093 回答
0

规范的第 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() {
            ...
        }
    }

    ...
}
于 2014-10-07T15:23:33.527 回答