Why there are no any compilation errors in the second example but there is following compilation error in the first example?
SomeConcreateClass.java:1: ISomeBaseInterface cannot be inherited with different arguments: <java.lang.Object> and <>
public class SomeConcreateClass
^
1 error
The only difference – class SomeDerivedClass is not parameterized in the second example.
Example1:
Do I understand correctly that in this example
public class SomeConcreateClass
extends SomeDerivedClass
implements ISomeInterface
{}
class SomeDerivedClass<T> /* <-------*/
extends SomeAbstractClass<Object>
implements ISomeInterface
{}
abstract class SomeAbstractClass<T>
implements ISomeBaseInterface<T>
{}
interface ISomeInterface extends ISomeBaseInterface<Object>
{}
interface ISomeBaseInterface<T>
{}
Example 2:
public class SomeConcreateClass
extends SomeDerivedClass
implements ISomeInterface
{}
class SomeDerivedClass /* <-------*/
extends SomeAbstractClass<Object>
implements ISomeInterface
{}
abstract class SomeAbstractClass<T>
implements ISomeBaseInterface<T>
{}
interface ISomeInterface extends ISomeBaseInterface<Object>
{}
interface ISomeBaseInterface<T>
{}
UPDATE:
Do I understand correctly that in example below all tree starting from SomeDerivedClass will be used as raw type?
Information that first parameter for SomeBaseClass is List will be lost.
Is it correct?
import java.util.List;
public class SomeConcreateClass
extends SomeDerivedClass
implements ISomeInterface
{
public static void main(String[] args) {
SomeConcreateClass c = new SomeConcreateClass();
List lst = c.getT(); //Type mismatch: cannot convert from Object to List
}
}
class SomeDerivedClass<T>
extends SomeBaseClass<List, T> /* <----- */
implements ISomeInterface
{}
class SomeBaseClass<T, M>
implements ISomeBaseInterface<T>
{
public T getT(){return null;}
}
interface ISomeInterface extends ISomeBaseInterface<List>
{}
interface ISomeBaseInterface<T>
{}
In short, use of raw type (i. e. use of generic type without type parameter) disables all generic-related stuff behind it.
It’s usually demonstrated by the following example:
You have the similar situation, but it’s related to inheritance rather than member access.
Here is a relevant quote from JLS 4.8 Raw Types:
In your first example,
SomeDerivedClassis generic, andSomeConcreteClassinherits it as a raw type. Thus,ISomeBaseInterface<Object>inherited through this branch of inheritance turns into its erasureISomeBaseInterface<>, butISomeInterfaceinherited directly still inheritsISomeBaseInterface<Object>. Since you cannot implement the same generic interface many times with different type parameters, compiler reports an error.In the second example,
SomeDerivedClassis not generic, therefore there are no problems with raw types.