为什么使用<t extends =“”superclass =“”>而不仅仅是Superclass?

时间:2017-07-16 11:32:55

标签: java generics

早上好,这是从oracle教程中获取的, 假设我们有

class Shape { /* ... */ }
class Circle extends Shape { /* ... */ }
class Rectangle extends Shape { /* ... */ }

方法

public static <T extends Shape> void draw(T shape) { /* ... */ }

我的问题如下,您为什么要使用<T extends Shape>代替Shape他们还没有回复同样的事情吗?在这种情况下是一个形状

2 个答案:

答案 0 :(得分:2)

如果这个draw方法没有返回任何内容,也许你是对的,但假设你有一个具有返回值的泛型方法:

public static <T extends Shape> T draw(T shape) { /* ... */ }

现在,使用类型绑定,您可以写:

Rectangle r = ...
Rectangle r2 = draw(r);

Circle c = ...
Circle c2 = draw(c);

另一方面,如果您将签名更改为

public static Shape draw(Shape shape) { /* ... */ }

你只能写:

Rectangle r = ...
Shape r2 = draw(r);

Circle c = ...
Shape c2 = draw(c);

或使用显式强制转换(在运行时甚至可能失败,因为现在draw可以返回Shape的任何子类型:

Rectangle r = ...
Rectangle r2 = (Rectangle) draw(r);

Circle c = ...
Circle c2 = (Circle) draw(c);

答案 1 :(得分:0)

  

他们还没有回复相同的东西吗?

是的,在这种情况下,考虑返回类型为void

<T extends Shape>使该方法可以接受Shape类型的输入或Shape的任何子类。

但是,如果你有这样的话:

public static <T extends Shape> T draw(T shape) {/* ... */}

然后接收类型可以是Shape Shape的任何子类。

如果返回类型为Shape,那么接收类型只能Shape而不是其子类。虽然您可以将draw()的返回值转换为适当的类型,但这很容易出错,并且在泛型的帮助下,我们可以消除这种负担。