The problem here is that, with the way you've parameterized it, i could be of type Interface1<Type1>, Interface1<Type2>, or Interface1<SomeOtherSubtypeOfType>.
Then you get to the second line...and you're trying to put a Type1 in it. The compiler can't allow that - what if it's an Interface<Type2>? Generics only work at compile time, not at runtime, so the compiler will prevent anything it can't be sure about.
There is a mechanism for using wildcard types and still being able to add objects. If you had i declared as type Interface1<? super Type>, then it would be different. That way the compiler could be certain that it would accept a Type (or Type1, Type2 etc.) as an argument, and it would compile.
(Of course, that's not consistent with declaring Interface1<T extends Type> in the first place - so if this was a real situation there's something wrong with the design somewhere).
T Mueller wrote:I was under the impression that the following statement
should allow Interface1<any class that extends Type>
Yes, that's correct.
But that means that i could actually be any of the following:
1. Interface1<Type> 2. Interface1<Type1> 3. Interface1<Type2> 4. etc
The ? is just a wildcard. The actual object that i references is not an Interface1<? extends Type>, it's going to be an Interface1<SomeUnknownClassThatExtendsType>.
In the third case, i.put(new Type1()) is clearly an error. But since the compiler doesn't know which of those cases it is, it can't allow any of them. The key, I think, to understanding generics is to ask yourself "what does the compiler know about this reference?".
I'm afraid without knowing what you're trying to achieve it's difficult for me to show you what the code should actually be.