Другие ответы уже обсуждают, как использовать UnaryOperator<T>
.Хотя этот подход обеспечивает безопасность типов в Java-обобщениях, вам все равно придется указывать тип при создании UnaryOperator
.Хотя я рекомендовал бы подход UnaryOperator
в большинстве ситуаций, вы конкретно задали вопрос (в комментариях), как можно избежать указания типа <T>
, даже если вам пришлось отказаться от безопасности типов.
Вы можетеВыполните MonoFunction
реализацию следующим образом (небезопасно и обычно не рекомендуется):
public class MonoFunction {
private UnaryOperator<Object> func;
@SuppressWarnings("unchecked")
public <T> MonoFunction(UnaryOperator<T> func) {
this.func = (UnaryOperator<Object>) func;
}
@SuppressWarnings("unchecked")
public <T> T apply(T obj) {
return (T) func.apply(obj);
}
}
Обратите внимание, что это , а не a @FunctionalInterface
, поэтому вам придется поставить свою лямбдуВыражение внутри вызова new MonoFunction(...)
выглядит следующим образом:
public class MonoFunctionTest {
public static void main(String[] args) {
A a;
B b;
MonoFunction foo = new MonoFunction((obj) -> {
System.out.println(obj);
return obj;
});
a = foo.apply(new A()); // toString in A
b = foo.apply(new B()); // toString in B
MonoFunction bad = new MonoFunction((A obj) -> {
System.out.println(obj);
return obj;
});
a = bad.apply(a); // toString in A
b = bad.apply(b); // ClassCastException: B cannot be cast to A
}
}
class A {
public String toString() { return "toString in A"; }
}
class B {
public String toString() { return "toString in B"; }
}
Я еще раз подчеркиваю, что это небезопасно, и, как показано, относительно легко получить ClassCastException
.