Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is Predicate<? super SomeClass> not applicable to Object?

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());
    }
}
like image 713
lexicore Avatar asked May 09 '18 08:05

lexicore


People also ask

Which of the below is the functional method of predicate T interface?

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.

Is predicate a functional interface?

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) .

Is predicate anonymous function?

A predicate doesn't have to be an anonymous function.

What does predicate mean in Java?

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.


1 Answers

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.

like image 168
Eran Avatar answered Oct 05 '22 09:10

Eran