Итак, то, что вы спрашиваете, невозможно из коробки, как сказал Джон, но вы все равно можете добиться аналогичного поведения, используя так называемый тип Either
, который используется для представления ситуации, когда вы можете выбрать один из двух типов.
Вы можете легко найти полностью реализованный класс Either
с помощью простого поиска в Google, например этот на github
Ниже приведен фрагмент кода:
public class Either<L, R> {
private final L left;
private final R right;
private final boolean isRight;
private Either(L left, R right, boolean isRight) {
this.left = left;
this.right = right;
this.isRight = isRight;
}
public static <L, R> Either<L, R> left(L left){
return new Either<>(left, null, false);
}
public static <L, R> Either<L, R> right(R right){
return new Either<>(null, right, true);
}
public <T> T fold(Function<L,T> foldLeft, Function<R, T> foldRight){
return isRight ? foldRight.apply(right) : foldLeft.apply(left);
}
}
Теперь предположим, что у вас есть интерфейс с каким-то методом, который должен принимать String
или StringBuilder
:
public interface IFooBar <T extends Either<? extends String, ? extends StringBuilder>>{
String doSomething(T t);
}
И реализация:
class FooBar implements IFooBar<Either<String, StringBuilder>> {
@Override
public String doSomething(Either<String, StringBuilder> either) {
return either.fold(s -> "String: " + s, sb -> "StringBuilder:" + sb);
}
}
Тогда вы можете просто использовать его так:
public static void main(String[] args) {
IFooBar<Either<String, StringBuilder>> fooBar = new FooBar();
// Since in this case it is single method interface you can even use lambda expression
// IFooBar<Either<String, StringBuilder>> fooBar = either -> either.fold(s -> "String: " + s, sb -> "StringBuilder:" + sb);
System.out.println(fooBar.doSomething(Either.left("Foo")));
System.out.println(fooBar.doSomething(Either.right(new StringBuilder("Bar"))));
}
Надеюсь, это вам поможет.