Reputation: 131
If I have:
public class MyClass{
MyClass(Object b){
//Some code here
}
}
And I do:
MyClass X = new MyClass(new SomeOtherClass());
It works just fine, im assuming, because every class has Object as a superclass.
But, if I do:
import java.util.function.Predicate;
public class MyClass{
MyClass(Predicate<Object> b){
//Some more code here
}
}
And then:
MyClass X = new MyClass((SomeOtherClass s) -> {
//Even more code
return true;
});
I get an error saying:
Incompatible parameter types in lambda expression: expected Object but found SomeOtherClass
Shouldn't I be able to send a SomeOtherClass
object in that lambda expression?
I'm using the Object
class because i wanna be able to recieve not only SomeOtherClass
, but also SomeOtherClassXPTO
.
I tried looking this up and found nothing so far, so my apologies in advance if this has been asked before.
Upvotes: 5
Views: 3934
Reputation: 16216
As you know, the following is valid:
Object o = new SomeOtherClass();
But, this doesn't apply to generics, because generics are not covariant:
Predicate<Object> p;
p = (SomeOtherClass s) -> false; // compiler error - incompatible parameter types...
The only possible assignment to the Predicate<Object>
is:
Predicate<Object> p = object -> ... ;
At the same time, the input to this predicate can be of any type:
p.test(new Object());
p.test("");
p.test(99);
As stated in the Yassin's answer, consider Predicate<? extends Type>
in order to gain flexibility.
Upvotes: 1
Reputation: 54148
Inheritance does not work for Generic parameter, the official doc about can be found here
You need to
MyClass(Predicate<? extends Object> b) {
//Some more code here
}
or
MyClass(Predicate<?> b) {
//Some more code here
}
Upvotes: 1
Reputation: 21975
Well, when you defined your predicate as Predicate<Object>
it's restricted to only accept objects which getClass()
method returns Object
.
For this method to work you would be doing something like Predicate<? extends Object>
but this does not make much sense. Use Predicate<?>
alone then.
Otherwise, another way to solve this is to find the common denominator of your two classes, probably a parent class and use Predicate<? extends ParentClass>
.
A final solution would be to create, depending on your application logic, an interface and implementing the interface by both objects to be able to something like the following Predicate<? extends YourInterface>
Upvotes: 3