Assume we have a predicate declared as Predicate<? super SomeClass>
. I would naively expect it to be applicable to any superclass of SomeClass
up the hierarchy, including Object
.
However this predicate is not applicable to Object
. I get the following error:
The method test(capture#3-of ? super SomeClass) in the type Predicate is not applicable for the arguments (Object)
Demo.
Why is Predicate<? super SomeClass>
not applicable to an instance of Object
?
The code:
import java.util.*;
import java.lang.*;
import java.io.*;
import java.net.URL;
import java.util.function.Predicate;
/* Name of the class has to be "Main" only if the class is public. */
class Ideone
{
public static void main (String[] args) throws java.lang.Exception
{
Predicate<? super URL> p = u -> u.getFile().isEmpty();
p.test(new Object());
}
}
Predicate<T> is a generic functional interface that represents a single argument function that returns a boolean value (true or false). This interface available in java. util. function package and contains a test(T t) method that evaluates the predicate of a given argument.
This is a functional interface and can therefore be used as the assignment target for a lambda expression or method reference. Represents a predicate (boolean-valued function) of one argument. This is a functional interface whose functional method is test(Object) .
A predicate doesn't have to be an anonymous function.
The predicate is a predefined functional interface in Java defined in the java. util. Function package. It helps with manageability of code, aids in unit-testing, and provides various handy functions.
For a Predicate<? super SomeClass>
variable, you can assign a Predicate<SomeClass>
instance, or a Predicate<Object>
instance.
However, you can't pass an Object
to the test()
method of a Predicate<SomeClass>
. You can only pass a SomeClass
instance.
Therefore you can't pass an Object
to the test()
method of a Predicate<? super SomeClass>
Consider the following:
Predicate<URL> p1 = u -> u.getFile().isEmpty();
Predicate<? super URL> p2 = p1;
p2
is referring to a Predicate<URL>
, so you can't pass a new Object()
to its test()
method.
In other words, in order for p.test(new Object())
to be accepted by the compiler, it must be valid for any Predicate
that can be assigned to the Predicate<? super URL> p
variable. Since the Predicate<URL>
Predicate
can be assigned to that variable, and its test()
method cannot accept an Object
, p.test(new Object())
cannot be accepted by the compiler.
BTW, in your specific example, you are creating a Predicate<URL>
, and URL
is a final class. Therefore, you should simply declare it as:
Predicate<URL> p = u -> u.getFile().isEmpty();
There's no reason for ? super
or ? extends
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With