Java:隐式类型转换或隐式toString()调用
在Java应用程序中,我创建了返回对象的方法 这是因为在某些地方,我调用这些方法作为(第三方)方法的参数,这些方法需要字符串参数作为输入。 而在其他地方,我调用这些方法作为(第三方)方法的参数,这些方法期望其他参数类型(T)作为输入 因此,根据调用我创建的方法的位置,代码如下所示:Java:隐式类型转换或隐式toString()调用,java,scala,aspectj,spring-aop,implicit-conversion,Java,Scala,Aspectj,Spring Aop,Implicit Conversion,在Java应用程序中,我创建了返回对象的方法 这是因为在某些地方,我调用这些方法作为(第三方)方法的参数,这些方法需要字符串参数作为输入。 而在其他地方,我调用这些方法作为(第三方)方法的参数,这些方法期望其他参数类型(T)作为输入 因此,根据调用我创建的方法的位置,代码如下所示: their.thirdPartyExpectsString(my.calculateEither().getLeft()); their.thirdPartyExpectsString(my.calculateEit
their.thirdPartyExpectsString(my.calculateEither().getLeft());
their.thirdPartyExpectsString(my.calculateEither() + "");
或
(我将other.toString()
定义为other.getLeft()
)
请注意,我无法更改第三方代码(无论如何,没有字节码操作也不行),我希望保留我的设计,在其中我从我的方法返回或
有没有办法简化我的代码,让它看起来像
their.thirdPartyExpectsString(my.calculateEither());
their.thirdPartyExpectsDouble(my.calculateEither());
也就是说,不必一直添加getLeft()/getRight()
或+“”
事实上,如果我不得不这样做的话,我也不会太在意
their.thirdPartyExpectsDouble(my.calculateEither().getRight());
因为我不必经常这么做。但是我不想在my.calculateEither()
返回Left
(字符串)时调用getLeft()或+“”
给定一个或,只需检查哪一侧的为空,就不难看出它是表示右还是左
但问题在于类型转换,即当thirdPartyExpectsString()
需要字符串,但得到或时出现编译错误
我能够通过AspectJ捕获my.calculateEither()
的返回值,但我看不到如何在返回建议后使用类似@的内容来让编译器理解我想要返回my.calculateEither().getLeft()
,即字符串
有什么想法吗?添加一个助手方法。由于不能向它们的
添加新方法,因此必须向自己的类添加一个静态
伪代码:
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())
将以下方法添加到或类的实现中:
@SuppressWarnings("unchecked")
public <T> T whichever() {
return (T) (isLeft() ? getLeft() : getRight());
}
将在第一次调用中工作得很好,在第三次调用中会引起<代码> CLSASTASTExtExt/Cuth>,只是一个期望,因为我们认为它是非法用例。
总之,很高兴知道它将在所有地方工作,其中我们隐式转换到的T类型可分配给或对象包含的实际值。不幸的是,如果不是这样的话,您只能在运行时发现。我不确定是否真正理解了这个问题,但是使用泛型方法而不是这两种方法如何?public T calculate(){…}您的包装器是自定义类吗?然后很容易引入到double的隐式转换。使用util.other会很尴尬。@Satoshi我所描述的my.calculateEither()
已经是一个泛型方法,带有泛型参数T(因为字符串是固定类型)。但是无论如何,对于您的签名,不管您将字符串值隐藏在什么位置-因为您在需要字符串参数的位置调用它,所以您必须执行类似于T.getString()
或T+“”
@som snytt的操作此应用程序是用Java编写的(在我看来,这整个设计理念都被打破了。如果你不想要类型安全,就不要使用Java。尽管我非常喜欢AOP,但这并不是使用它的适当理由。在我的情况下,这将是很困难的,因为thirdpartyeexpectsDuuble
和中的其他方法也会返回它们的,并且它们的中有许多这样的满足hods.My calls看起来像他们的.expectsString_1(..).expectsString_4(..).expectsString_2(..).expectsString_9(..)
所以我的助手类会非常大。哇,这真是一个聪明的操作。它几乎是隐式类型转换。:)Bravisimo@是的,这是我能想到的最多的了。我也在考虑基于AspectJ的解决方案,但我找不到一种方法。不过,直接字节码操作可能是可行的。对我来说,你的想法比AspectJ的方式要好。因为它不需要使编译过程复杂化。至于类型安全问题-在这个特定的应用程序中,或者
作为左
或者右
的创建以及在何处使用它们是自动完成的,因此简单代码的好处大于误用我的代码的风险。我还发布了一篇关于这个主题的后续文章,它实际上有一个名字:)
@SuppressWarnings("unchecked")
public <T> T whichever() {
return (T) (isLeft() ? getLeft() : getRight());
}
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());