Java лямбда: ожидаемый объект, но найденный MyClass - PullRequest
0 голосов
/ 12 мая 2018

Если у меня есть:

public class MyClass{
    MyClass(Object b){
        //Some code here
    }
}

И я делаю:

MyClass X = new MyClass(new SomeOtherClass());

Это работает просто отлично, я предполагаю, потому что у каждого класса есть Object как суперкласс.

Но если я сделаю:

import java.util.function.Predicate;
public class MyClass{
    MyClass(Predicate<Object> b){
        //Some more code here
    }
}

А потом:

MyClass X = new MyClass((SomeOtherClass s) -> {
    //Even more code
    return true;
});

Я получаю сообщение об ошибке:

Incompatible parameter types in lambda expression: expected Object but found SomeOtherClass

Разве я не смогу отправить объект SomeOtherClass в этом лямбда-выражении? Я использую класс Object, потому что хочу получить не только SomeOtherClass, но и SomeOtherClassXPTO. Я попытался найти это и ничего не нашел до сих пор, поэтому мои извинения заранее, если об этом уже спрашивали.

Ответы [ 3 ]

0 голосов
/ 12 мая 2018

Что ж, когда вы определили свой предикат как Predicate<Object>, он ограничен только принятием объектов, которые getClass() возвращает метод Object.

Чтобы этот метод работал, вы должны выполнить что-то вроде Predicate<? extends Object>но это не имеет особого смысла.Тогда используйте только Predicate<?>.

В противном случае, другой способ решить эту проблему - найти общий знаменатель ваших двух классов, возможно, родительский класс, и использовать Predicate<? extends ParentClass>.

Окончательное решениебыло бы создать, в зависимости от логики вашего приложения, интерфейс и реализацию интерфейса обоими объектами, чтобы иметь возможность что-то вроде следующего Predicate<? extends YourInterface>

0 голосов
/ 12 мая 2018

Как известно, действует следующее:

Object o = new SomeOtherClass();

Но это не относится к генерикам, потому что генерики не являются ковариантными :

Predicate<Object> p;

p = (SomeOtherClass s) -> false; // compiler error - incompatible parameter types...

Единственное возможное присвоение Predicate<Object>:

Predicate<Object> p = object -> ... ;

В то же время входные данные для этого предиката могут быть любого типа:

p.test(new Object());
p.test("");
p.test(99);

Как указано в ответе Ясина, рассмотрите Predicate<? extends Type>, чтобы получить гибкость.

0 голосов
/ 12 мая 2018

Наследование не работает для параметра Generic, официальный документ о нем можно найти здесь


Вам нужно

MyClass(Predicate<? extends Object> b) {
    //Some more code here
}

или

MyClass(Predicate<?> b) {
    //Some more code here
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...