Reputation: 16795
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>
{}
Upvotes: 3
Views: 945
Reputation: 242686
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:
class Foo<T> { public List<String> m() { ... } }
String s1 = new Foo<Object>().m().get(0); // Compiles
String s2 = new Foo().m().get(0); // Cannot cast Object to String
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:
The superclasses (respectively, superinterfaces) of a raw type are the erasures of the superclasses (superinterfaces) of any of its parameterized invocations.
In your first example, SomeDerivedClass
is generic, and SomeConcreteClass
inherits it as a raw type. Thus, ISomeBaseInterface<Object>
inherited through this branch of inheritance turns into its erasure ISomeBaseInterface<>
, but ISomeInterface
inherited directly still inherits ISomeBaseInterface<Object>
. Since you cannot implement the same generic interface many times with different type parameters, compiler reports an error.
In the second example, SomeDerivedClass
is not generic, therefore there are no problems with raw types.
Upvotes: 3