Java:部分应用的泛型类 - 如何消除冗余类型参数?

时间:2016-03-13 18:23:25

标签: java generics

在我的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,其中左类型参数设置为String。

所以我想这样做的方法是:

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课程之外,是否有更好,更优雅的方法来实现这一目标?

1 个答案:

答案 0 :(得分:1)

你在这里有一个静态的方法:

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);
}

所以基本上你需要做的是重构完整的任一类,用String替换每个“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);
}

不幸的是,你可以做的更多(除了显而易见的,只是在评论中提到每次都写“String”。这可能是多余的,但它也有助于你清楚地理解代码。所以我它很有用)

相关问题