After over three hours on the ground, the flight finally left for Newark.
![](http://lh3.ggpht.com/_UQ8SBm-mQxI/SnDU7A8ah5I/AAAAAAAAe0s/ivAyL_s-xGs/path.jpg)
when to made several rotations around an arbitrary area
![](http://lh3.ggpht.com/_UQ8SBm-mQxI/SnDU65KDhtI/AAAAAAAAe0k/tclOT14TzGM/zoom.jpg)
then redirected to Boston.
![](http://lh6.ggpht.com/_UQ8SBm-mQxI/SnDVZ6-m9uI/AAAAAAAAe00/JUoOQI_PNrU/redirected.jpg)
This is not Judy's day.
![]() | ![]() |
![]() | ![]() |
public interface Model{T extends Model{T}} {
T read(InputStream in);
T write(OutputStream out);
}
public class MyModel implements Model{MyModel}Thanks to the covariance, I can write a method chain like this:{
public MyModel read(InputStream in) {
...
}
public MyModel write(OutputStream out) {
...
}
public MyModel setName(String name) {
...
return this;
}
public String getName() { ... }
}
new MyModel()
.read(in)
.setName("foo")
.setStopAtMain(false)
...
.write(out);
public interface Model {And the method chain would result in a syntax error:
Model read(InputStream in);
Model write(OutputStream out);
}
class MyModel implements Model {
public Model read(InputStream in) { ... }
public Model write(OutputStream out) { ... }
...
}
public static void foo() {Which you could hack around with an ugly cast:
new MyModel()
.read(in)
.setName("foo")
^ The method setName(String) is undefined
for the type Model.
.write(out);
}
public static void foo() {Back to the Java 5 example: My point is just this: covariant return types don't require generics. All that messy code in version 1 could look much simpler because covariant return types exist on their own without generics:
((MyModel) new MyModel()
.read(in))
.setName("foo")
.write(out);
}
public interface Model{{T extends Model{T}}
TModel read(InputStream in);
TModel write(OutputStream out);
}
public class MyModel implements ModelLesson learned: I know generics fairly well, but there's a difference between knowing when it's useful and when it isn't. Said another way: when you have a Generic hammer everything looks like a generic nail.{{MyModel}
public MyModel read(InputStream in) {
...
}
public MyModel write(OutputStream out) {
...
}
public MyModel setName(String name) {
...
return this;
}
public String getName() { ... }
}