在我的Java应用程序中,我创建了返回Either<String, T>
对象的方法。
这是因为在某些地方,我将这些方法作为(第3方)方法的参数调用,这些方法希望将String参数作为输入。
在其他地方,我将这些方法作为(第三方)方法的参数调用,这些方法需要其他一些参数类型(T)作为输入。
因此,根据我调用创建的方法的位置,代码如下所示:
their.thirdPartyExpectsString(my.calculateEither().getLeft());
their.thirdPartyExpectsString(my.calculateEither() + "");
要么
their.thirdPartyExpectsDouble(my.calculateEither().getRight());
(我将
Either.toString()
定义为Either.getLeft()
)。请注意,我无法更改第三方代码(无论如何不能没有字节码操作),并且我希望保持我的设计能够从方法中返回
Either
。有没有一种方法可以简化我的代码并使它看起来像
their.thirdPartyExpectsString(my.calculateEither());
their.thirdPartyExpectsDouble(my.calculateEither());
也就是说,不必一直添加
getLeft()/getRight()
或+ ""
吗?其实,如果我必须做的话,这不会打扰我
their.thirdPartyExpectsDouble(my.calculateEither().getRight());
因为我不必经常这样做。但是我想摆脱当
getLeft()
返回+ ""
(字符串)时调用my.calculateEither()
或Left
的需要。给定
either
,只需检查哪一侧具有Right
,就不难发现它代表的是Left
还是null
。但是问题出在类型转换上,即
thirdPartyExpectsString()
需要String
但得到Either
时的编译错误。我可以通过AspectJ捕获
my.calculateEither()
的返回值,但是我看不到如何使用类似@AfterReturning
的建议的方式来使编译器理解我要返回my.calculateEither().getLeft()
(即String
)的方法。 ...有任何想法吗?
最佳答案
将以下方法添加到Either
类的实现中:
@SuppressWarnings("unchecked")
public <T> T whichever() {
return (T) (isLeft() ? getLeft() : getRight());
}
请注意,我故意忽略有关未经检查的强制转换的警告,并且如果在与之交互的外部API需要左值但在
ClassCastException
实例上调用它的地方使用它,的确会导致Either
其中包含一个正确的值。此方法将根据使用位置进行隐式转换。它将转换为T类型,然后将其传递给另一个需要T类型参数的方法,或者尝试将方法返回值分配给T类型的变量。因此,下面的演示代码:
Either<String, Double> containsString = Either.<String, Double>left("first");
Either<String, Double> containsDouble = Either.<String, Double>right(2d);
their.expectsString(containsString.whichever());
their.expectsDouble(containsDouble.whichever());
their.expectsDouble(containsString.whichever());
可以在第一次调用中很好地工作,并且会在第三次调用中导致
ClassCastException
,就像我们期望的那样,因为我们认为这是非法用例。总之,很高兴知道它将在所有我们隐式转换为T类型的对象都可以分配给
Either
对象所包含的实际值的地方使用。不幸的是,如果不是这种情况,您将只能在运行时查找。关于java - Java:隐式类型转换或隐式toString()调用,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35953155/