Why is List<SubClass> incompatible with List<T extends SuperClass>? - java

interface Receiver {
public <T extends HasId> void doSomethingWithList(List<T> list);
}
also,
class SubClass implements HasId {}
but
List<SubClass> list = getList();
receiver.doSomethingWithList(list);
fails to compile, complaining doSomethingWithList is not applicable for the arguments List<SubClass>
Where's my mistake?

It looks fine to me. Can it be that you used the wrong List class (i.e. not java.util.class but java.awt.List) in one of the declarations. Perhaps in the interface. Can you double-check import statements? I've made this mistake myself in the past, and it is valid lead on this case :-)

code compiles fine without any problem.

Like irreputable, my quick implementation of your code compiles and runs just fine. Perhaps this can give you some leads; perhaps the issue has more to do with your implementation in regards to Java's support of generic polymorphism.
It seems that you're using an interface rather than class inheritance, but your question title says List<T extends SuperClass>...

Related

Java Generics and A implements B

I know in Java Generics, there is T extends something, but I want T implements something.
Is there any way to achieve this other than using the explicit cast?
For instance, I want to make sure everything passed to sorting algorithm implements Comparable. Implements, not extends.
Thank you.
For generic type bounds, extends isn't limited to classes; you can also use it for interfaces. For example, <T extends Runnable> is OK.

Java Generics Interface casting

I stumbled across a Java casting situation involving Generics and Interfaces that I do not understand.
Please consider the following code where I create a List<Interface1>. And then get() an element and cast it to Interface2 without compiler error although these two interfaces are completely unrelated.
import java.util.*;
public class Main {
public static void main(String ... args) {
List<Interface1> list = new ArrayList<>();
list.add(new Interface1() {});
Interface1 ok = list.get(0);
Interface2 why = (Interface2)list.get(0);
}
}
interface Interface1 {
}
interface Interface2 {
}
Can anyone explain why there is not compiler error for the cast at the second get(0)?
Two side notes: Executing the class throws a ClassCastException (as expected). And using two classes instead of interfaces does actually generate compile errors.
This behaviour is unrelated to generics: you can cast any interface to any other without compile errors.
You cannot do this with classes because Java can check at compile time whether one class can be casted to another.
With interfaces however the cast might succeed or fail, depending on the class that is actually implementing the interface. This can be discovered only at runtime though.
If you have a type which implements Interface1 it may as well implement Interface2. Hence the compiler will not blame you, because at runtime the cast may succeed.
This is because JAVA supports multiple interface implementations. As we can have any number of classes of any types(any parent class) that can implement an interface, JVM design is such that untill runtime one cannot identify which type is being passed in place that interface.So there can be any interface placed in the ArryList
The compiler does not know that this won't work: You could have a instance of type Interface2 that is also of type Interface1 (for ex: class ImplementingClass implements Interface1,Interface2). Then the cast would be fine.
"using two classes instead of interfaces does actually generate compile errors."
In this situations compiler knows that it won't work, and due to this you are getting compilation error in this case.
There is possibility, that sub class of Interface1 can be a sub class of Interface2 also. So, it doesn't give the compilation error.
It not generic problem. JVM nothing "known" about compatibilities between Interface1 and Interface2. So you get ClassCastException.

Self bounded generics

Is there is any actual difference between these this generic
public class SelfBounded <T extends SelfBounded<T>>{}
and this one
public class SelfBounded <T extends SelfBounded>{}
?
If yes, then how can I observe them?
There are a lot of similar questions here already.
You can read the following article
Or the following questions:
Java Enum definition
Why in java enum is declared as Enum<E extends Enum<E>>
What would be different in Java if Enum declaration didn't have the recursive part
The second one uses a raw type, which should never be used.
But actually neither of these declarations are normally useful. You should almost certainly just use
public class SelfBounded <T>

Getting a generic type of implementing class

Has this interface:
public interface Cloneable<T>
{
public T clone();
}
And it's implementing class:
public class Clazz implements Cloneable<Clazz>
{
public Clazz clone();
}
Can i avoid this?:
implements Cloneable<Clazz>
It will be simply implements Cloneable. Sorry for my english, i from Russia...
Well you could write implements Cloneable, but then you'd be using the raw type, which is generally a bad idea.
For the sake of stronger typing, you're better off sticking with what you've got.
If you leave out the <Clazz> it is treated as if you used <Object>.
If that is acceptable then go for it. Not recommended though unless you really want to lose some of your type safety.
Wasn't there a Java Puzzlers that mentioned this ... I can't find it.
Found it here. Go to about 38:00 where they are discussing the Glommer type.
Jon is correct - Raw types are not the same as <Object> and they are scary.
Solution: public interface Cloneable<T extends Cloneable<T>>

Java bounded wilcard type

I need to define a generic class, and the type parameter must be an enum. I think it should look something like
public class <T> MyClass<T extends Enum<T>> {
}
But I can't seem to figure out the exact syntax. I should mention that I need a way to refer to the type (within MyClass) that it is instantiated with.
Thanks!
public class MyClass<T extends Enum<T>> { }
While the approved answer looks syntactically correct, what's the scenario for such a declaration? Are you trying to write some class that can operate on any enum-defined type, like java.util.EnumSet or java.util.EnumMap? It's an unusual arrangement, so be sure you really need it in order to meet your requirements.

Categories