无赋值的 Java 三元
Posted
技术标签:
【中文标题】无赋值的 Java 三元【英文标题】:Java Ternary without Assignment 【发布时间】:2013-04-05 07:34:26 【问题描述】:有没有办法在不进行赋值或伪造赋值的情况下进行 java 三元运算?
我喜欢在执行一堆 if/then/else 时的简洁三元代码。
我希望能够基于布尔代数语句调用两个 void 函数之一。
类似:
(bool1 && bool2) ? voidFunc1() : voidFunc2();
我的函数是返回类型void
,所以如果有办法在分配中伪造它以使其工作,那么我可以接受......我想看看怎么做:)
【问题讨论】:
@VenomFangs 您可以更改您的函数以始终返回一个常量值,并将此返回值分配给一个虚拟变量。但这不值得麻烦 - 恐怕代码看起来很愚蠢。最好按照您已经知道应该做的那样去做。 【参考方案1】:不,你不能这样做。 spec says so。
条件运算符具有三个操作数表达式。 ?出现 在第一个和第二个表达式之间,并且 : 出现在 第二个和第三个表达式。
第一个表达式必须是 boolean 或 Boolean 类型,或者 发生编译时错误。
这是第二个或第三个操作数的编译时错误 表达式是 void 方法的调用。
[编辑]
既然您询问了反射,这里有一个解决方案。我不推荐这个。我发布它只是因为你问了。
public class MyCall
public void a()System.out.println("a");
public void b()System.out.println("b");
public static void main(String... args)
new MyCall().go();
public void go()
Class<? extends MyCall> class1 = this.getClass();
Method aMethod = class1.getMethod("b", null);
Method bMethod = class1.getMethod("a", null);
Object fake = false ? aMethod.invoke(this, null) : bMethod.invoke(this, null);
Object fake2 = true ? aMethod.invoke(this, null) : bMethod.invoke(this, null);
在一天结束时,您必须问自己,简洁是否可以提高代码的可读性(想想 for-each 循环)。这些解决方案都没有提高代码的可读性恕我直言。如果我是你,我宁愿选择这个。
if(condition)
a();
else
b();
我实际上是 for 包括大括号,即使循环只包含一行,但是由于您要追求清晰的代码,所以上面的 sn-p 应该可以。
【讨论】:
关于反射评论的任何想法:***.com/questions/4830843/… 有没有办法让 void 反映为 null 然后将 null 分配给一个对象? 用反射解决方案编辑了我的答案。当然是为了学术目的:) 回答我提出的问题,所以我会接受答案...我的实际代码看起来更像 TGMCians 显示的内联 if/then/else 的代码。 :) 这已经得到了很长时间的回答,但我有一个想法。 (注意:我不是专业人士)。如果他让那些 void 函数返回一个整数会怎样。说 - 1。然后他运行int fake = bool ? method1 : method2;
他们都返回 - 1 但所需的代码仍然运行。我使用它,还没有遇到任何问题。【参考方案2】:
不,你不能这样做。
如果不喜欢做更多的陈述,你可以更喜欢这种风格。
if(bool1 && bool2) voidFunc1(); else voidFunc2();
在三元运算符中,操作数必须是非空表达式;即它们必须产生一些实际价值。
【讨论】:
我喜欢这个演示文稿......如果没有其他人可以告诉我一种方法,我会接受这个答案。例如。通过将 void 反射为 null...等。【参考方案3】:如果您真的-真的想使用 ternany 操作,那么有一个技巧。 但这是非常糟糕的代码,仅用于展示语言能力。 我绝不会建议将此代码投入生产,甚至不会向您的朋友展示。
int dummy = (bool1 && bool2) ? new Object()
public int hashCode()
yourFunction1();
// ...
yourFunctionN();
return 0;
;
.hashCode() : new Object()
public int hashCode()
yourAnotherFunction1();
// ...
yourAnotherFunctionN();
return 0;
;
.hashCode();
【讨论】:
【参考方案4】:有没有办法在不进行赋值或伪造赋值的情况下进行 java 三元运算?
好的,所以当你写这样的语句时:
(bool1 && bool2) ? voidFunc1() : voidFunc2();
代码有两个明显的问题:
条件表达式的第二个和第三个操作数1 不能调用 void 方法。参考:JLS 15.25.
表达式不是语句,除非它是赋值表达式或方法调用或对象创建。参考:JLS 14.8.
事实上,第二个问题是语法错误,我希望任何主流 Java 编译器都会报告它而不是第一个问题。只有当你这样做时,第一个问题才会暴露出来:
SomeType dummy = (bool1 && bool2) ? voidFunc1() : voidFunc2();
或
gobble((bool1 && bool2) ? voidFunc1() : voidFunc2());
其中gobble
是一个什么都不做的方法……除了“消耗”其参数的值。
AFAIK,没有可以接受原始表达式的上下文。
但是,有一些方法可以包装 void
函数,以便可以在条件表达式中调用它们。这是一个:
int dummy = (bool1 && bool2) ?
() -> voidFunc1(); return 0; :
() -> voidFunc2(); return 0;;
1 - “条件表达式”是 Java 语言规范中用于此构造的主要术语。在 Oracle Java 教程中称为“三元条件运算符”。
【讨论】:
以上是关于无赋值的 Java 三元的主要内容,如果未能解决你的问题,请参考以下文章
JAVA语言运算符(算数运算符赋值运算符比较运算符逻辑运算符三元运算)