Guice punches erasure in the face!
Java 5 Type Erasure is frustrating. I'm coding along, enjoying the glorious type safety of generics. And then I try to do a little more with theTs, and erasure shows up, "You can't do that!" I can't test an object if it really is a T. I can't inspect T.class using reflection. And I certainly can't new up a T. Yuck.We're in a unique situation with Guice. Its type literals and injection points have complete generic information. It can follow long chains of type variables throughout an object model. In my app, I've got a
Robot<T> that injects a Claw<T>. When I request a Robot<Adamantium>, Guice knows to find an adamantium claw.And now, this type information is available to application code. I can write a
Claw<T> class that actually knows what T is at runtime!Consider
 GuardingList<T>, which enforces type safety at runtime:class GuardingList<T> extends AbstractList<T> {
  private final TypeLiteral<T> elementType;
  private final ArrayList<T> delegate = new ArrayList<T>();
  @Inject
  GuardingList(TypeLiteral<T> elementType) {
    this.elementType = elementType;
  }
  public boolean add(T t) {
    checkArgument(elementType.getRawType().isInstance(t),
        "Cannot add %s which is not of type %s", t, elementType);
    return delegate.add(t);
  }
  public T get(int i) {
    return delegate.get(i);
  }
  public int size() {
    return delegate.size();
  }
}TypeLiteral<T>. The GuardingList blows up when I add an invalid element:  public static void main(String[] args) {
    Injector injector = Guice.createInjector();
    List<String> listOfString = injector.getInstance(
        new Key<GuardingList<String>>() {});
    listOfString.add("A");
    listOfString.add("B");
    /* totally unsafe, but this compiles and runs */   
    List<Object> rawList = (List) listOfString;
    /* throws an IllegalArgumentException, since the GuardingList
        knows that its elements must be Strings */
    rawList.add(666); 
  }Reify today.



