Search code examples
javagenericsguice

Binding instances without class arg in Guice


Why doesn't this workin Guice?

binder().bind(instance.getClass()).toInstance(instance);

I don't quite understand which generics edge case this violates, it looks sound to me. The error message in IntelliJ is:

toInstance (capture<? extends java.lang.Object>) in LinkedBindingBuilder cannot be applied to (java.lang.Object)

 


Solution

  • The compiler doesn't know that instance.getClass() is related to instance.

    Say instance is a Number: instance.getClass() is a Class<? extends Number>, because instance might be an Integer.

    And then the type inference algorithm doesn't know that instance is an instance of that Class<? extends Number>. By the PECS mnemonic, toInstance is a consumer method, but because it's bounded by an extends bound, the only thing you can pass to it is literal null.

    I can't think of a clean way to do this, without some warning suppression. But in this case it's fine to suppress (provided instance is an instance of a reifiable class): you know more than the compiler about the types, so go ahead and use the escape hatch.