在我的Java应用程序中,我创建了返回Either<A, B>
对象的方法。
然而,我真正使用的类型是Either<String, T>
,即 String
始终是左侧类型参数,而右侧参数可以是任何类型。
这是我正在使用的functionaljava Either
实现:
https://github.com/functionaljava/functionaljava/blob/master/core/src/main/java/fj/data/Either.java
这里Either
定义为:
public abstract class Either<A, B>
为了使我的代码不那么冗长,我想创建一个泛型类LeftAppliedEither<T>
,它将表示一个Either
,其中左类型参数设置为字符串。
所以我想这样做的方法是:
public abstract class LeftAppliedEither<T> extends Either<String, T> {}
但是,这不起作用。
首先,Either
不能由我扩展,因为它唯一的构造函数被定义为 private
。
其次,假设我已经解决了第一个问题,只需将Either
的代码复制到我的代码中(我们称之为MyEither
)并删除私有构造函数(并解决一些小的编译错误)。
所以我的代码中有以下类:
package fj.data;
//import ....
public abstract class MyEither<A, B> {
// private MyEither() {
//
// }
//the rest of the code is more or less like in the original Either
}
不过,我会遇到以下问题:
我无法编写以下代码:
LeftAppliedEither<Integer> hello = LeftAppliedEither.left("hello");
我只能做这样的事情:
MyEither<String,Integer> hello = LeftAppliedEither.left("hello");
好吧,这违背了我进行此更改的全部原因 - 我不希望在我的代码中使用具有两个参数的泛型类型,因为指定左String
是多余的。
除了重写整个LeftAppliedEither
类之外,还有更好、更优雅的方法来实现这一点吗?
你在这里得到的是一个静态方法:
LeftAppliedEither<Integer> hello = LeftAppliedEither.left("hello");
此静态方法不受继承的影响。正如您在代码中看到的,它带来了自己的泛型。所以继承在这里对你没有帮助:
/**
* Construct a left value of either.
* @param a The value underlying the either.
* @return A left value of either.
*/
public static <A, B> Either<A, B> left(final A a) {
return new Left<A, B>(a);
}
所以基本上你需要做的是重构完整的任一类,用一个字符串替换每个"A",并删除泛型参数中的所有"A",如以下示例所示:
/**
* Construct a left value of either.
* @param a The value underlying the either.
* @return A left value of either.
*/
public static <B> MyEither<B> left(final String a) {
return new MyLeft<B>(a);
}
不幸的是,您可以做的不多(除了显而易见的,只需每次都写"字符串",如评论中所述。它可能是多余的,但它也可以帮助您清楚地理解代码。所以我摔倒了很有用)