早上好,这是从oracle教程中获取的, 假设我们有
class Shape { /* ... */ }
class Circle extends Shape { /* ... */ }
class Rectangle extends Shape { /* ... */ }
方法
public static <T extends Shape> void draw(T shape) { /* ... */ }
我的问题如下,您为什么要使用<T extends Shape>
代替Shape
? 他们还没有回复同样的事情吗?在这种情况下是一个形状。
答案 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()
的返回值转换为适当的类型,但这很容易出错,并且在泛型的帮助下,我们可以消除这种负担。