Java: 隐式类型转换,或隐式 toString() 调用
Java: implicit type conversion, or implicit toString() invocation
在我的 Java 应用程序中,我创建了 return Either<String, T>
对象的方法。
这是因为在某些地方,我调用这些方法作为(第 3 方)方法的参数,这些方法需要 String 参数作为输入。
而在其他地方,我调用这些方法作为(第 3 方)方法的参数,这些方法需要一些其他参数类型 (T) 作为输入。
因此,根据调用我创建的方法的位置,代码如下所示:
their.thirdPartyExpectsString(my.calculateEither().getLeft());
their.thirdPartyExpectsString(my.calculateEither() + "");
或
their.thirdPartyExpectsDouble(my.calculateEither().getRight());
(我把Either.toString()
定义为Either.getLeft()
)。
注意,我不能更改第 3 方代码(无论如何不能没有字节码操作),并且我想保留我的设计 return Either
从我的方法。
有没有办法简化我的代码并使其看起来像
their.thirdPartyExpectsString(my.calculateEither());
their.thirdPartyExpectsDouble(my.calculateEither());
也就是说,不必一直添加 getLeft()/getRight()
或 + ""
?
实际上,如果我不得不这样做,我并不介意
their.thirdPartyExpectsDouble(my.calculateEither().getRight());
因为我不必经常这样做。但是我想摆脱在 my.calculateEither()
return 是 Left
(字符串)时调用 getLeft()
或 + ""
的需要。
给定一个 either
,不难看出它代表 Right
还是 Left
,只需检查哪一侧有 null
.
但问题出在类型转换上,即 thirdPartyExpectsString()
期望 String
但得到 Either
时的编译错误。
我能够通过 AspectJ 捕获 my.calculateEither()
的 return 值,但我看不到如何使用 @AfterReturning
之类的建议让编译器理解我的方法想要returnmy.calculateEither().getLeft()
,即String
.....
有什么想法吗?
添加辅助方法。由于您无法将新方法添加到 their
,因此您必须将 static
添加到您自己的 class。
伪代码:
public static void thirdParty(Their their, Either either) {
if (either.isLeft())
their.thirdPartyExpectsString(either.getLeft());
else
their.thirdPartyExpectsDouble(either.getRight());
}
您现在可以拨打:
MyHelper.thirdParty(their, my.calculateEither())
将以下方法添加到 Either
class 的实现中:
@SuppressWarnings("unchecked")
public <T> T whichever() {
return (T) (isLeft() ? getLeft() : getRight());
}
请注意,我故意忽略了有关未经检查的转换的警告,如果您在与外部 API 接口的地方使用它,确实会导致 ClassCastException
left 值,但您在包含 right 值的 Either
实例上调用它。此方法将根据您的使用位置进行 隐式转换 。它将转换为 T 类型,您将其传递给另一个需要类型 T 参数的方法,或者您尝试将方法 return 值分配给类型 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 应用程序中,我创建了 return Either<String, T>
对象的方法。
这是因为在某些地方,我调用这些方法作为(第 3 方)方法的参数,这些方法需要 String 参数作为输入。 而在其他地方,我调用这些方法作为(第 3 方)方法的参数,这些方法需要一些其他参数类型 (T) 作为输入。
因此,根据调用我创建的方法的位置,代码如下所示:
their.thirdPartyExpectsString(my.calculateEither().getLeft());
their.thirdPartyExpectsString(my.calculateEither() + "");
或
their.thirdPartyExpectsDouble(my.calculateEither().getRight());
(我把Either.toString()
定义为Either.getLeft()
)。
注意,我不能更改第 3 方代码(无论如何不能没有字节码操作),并且我想保留我的设计 return Either
从我的方法。
有没有办法简化我的代码并使其看起来像
their.thirdPartyExpectsString(my.calculateEither());
their.thirdPartyExpectsDouble(my.calculateEither());
也就是说,不必一直添加 getLeft()/getRight()
或 + ""
?
实际上,如果我不得不这样做,我并不介意
their.thirdPartyExpectsDouble(my.calculateEither().getRight());
因为我不必经常这样做。但是我想摆脱在 my.calculateEither()
return 是 Left
(字符串)时调用 getLeft()
或 + ""
的需要。
给定一个 either
,不难看出它代表 Right
还是 Left
,只需检查哪一侧有 null
.
但问题出在类型转换上,即 thirdPartyExpectsString()
期望 String
但得到 Either
时的编译错误。
我能够通过 AspectJ 捕获 my.calculateEither()
的 return 值,但我看不到如何使用 @AfterReturning
之类的建议让编译器理解我的方法想要returnmy.calculateEither().getLeft()
,即String
.....
有什么想法吗?
添加辅助方法。由于您无法将新方法添加到 their
,因此您必须将 static
添加到您自己的 class。
伪代码:
public static void thirdParty(Their their, Either either) {
if (either.isLeft())
their.thirdPartyExpectsString(either.getLeft());
else
their.thirdPartyExpectsDouble(either.getRight());
}
您现在可以拨打:
MyHelper.thirdParty(their, my.calculateEither())
将以下方法添加到 Either
class 的实现中:
@SuppressWarnings("unchecked")
public <T> T whichever() {
return (T) (isLeft() ? getLeft() : getRight());
}
请注意,我故意忽略了有关未经检查的转换的警告,如果您在与外部 API 接口的地方使用它,确实会导致 ClassCastException
left 值,但您在包含 right 值的 Either
实例上调用它。此方法将根据您的使用位置进行 隐式转换 。它将转换为 T 类型,您将其传递给另一个需要类型 T 参数的方法,或者您尝试将方法 return 值分配给类型 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
对象包含的实际值的所有地方。不幸的是,你只能在 运行 时间 发现,如果不是这样的话。