Skip to content

Instantly share code, notes, and snippets.

@gclaramunt
Created June 12, 2012 19:34
Show Gist options
  • Save gclaramunt/2919649 to your computer and use it in GitHub Desktop.
Save gclaramunt/2919649 to your computer and use it in GitHub Desktop.
Phantom types in Java
public class AirTrafficController {
public static Plane<Landed> land(Plane<Flying> p) {
return new Plane<Landed>(p);
}
public static Plane<Flying> takeOff(Plane<Landed> p) {
return new Plane<Flying>(p);
}
public static void main(String[] args){
Plane<Landed> p=Plane.newPlane();
Plane<Flying> fly=takeOff(p);
Plane<Landed> land=land(fly);
//doesn't compile:
//Plane<Landed> reallyLanded=land(land);
//Plane<Flying> reallyFlying=takeOff(fly);
}
}
public interface FlightStatus {
}
public interface Flying extends FlightStatus{
}
public interface Landed extends FlightStatus {
}
public class Plane<Status extends FlightStatus> {
private Plane(){
// blah blah blah
}
public Plane(Plane<? extends FlightStatus > p){
//copy whatever info we need
}
public static Plane<Landed> newPlane(){
return new Plane<Landed>();
}
}
@jsuereth
Copy link

Probably should have private constructor so Planes can't be created in any old state.

Plane<java.sql.Driver> b52 = new Plane()   // That's right.  Fly over the database, and DROP THE BOMB, Mr. death plane.

@gclaramunt
Copy link
Author

yeah, private is a good idea.
I thought also on making Status extend a common FlightStatus

@gclaramunt
Copy link
Author

There you go...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment