33

有没有办法在不进行分配或伪造分配的情况下进行 java 三元运算?

我喜欢在执行一堆 if/then/else 时的简洁三元代码。

我希望能够基于布尔代数语句调用两个 void 函数之一。

就像是:

(bool1 && bool2) ? voidFunc1() : voidFunc2();

我的函数是返回类型的void,所以如果有办法在分配中伪造它以使其工作,那么我可以接受......我想看看如何做到这一点:)

4

4 回答 4

29

不,你不能那样做。规范是这么说的。

条件运算符具有三个操作数表达式。? 出现在第一个和第二个表达式之间,并且 : 出现在第二个和第三个表达式之间。

第一个表达式必须是 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();

即使循环只包含一行,我实际上也包含大括号,但是由于您要使用清晰的代码,所以上面的代码片段应该可以。

于 2013-04-12T17:09:52.763 回答
12

不,你不能这样做。

如果不喜欢让它更多的陈述,你可以更喜欢这种风格。

if(bool1 && bool2) voidFunc1(); else voidFunc2();

在三元运算符中,操作数必须是非空表达式;即它们必须产生一些实际价值。

于 2013-04-12T17:05:05.300 回答
2

如果您真的真的想使用 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();
于 2013-04-12T17:24:19.660 回答
2

有没有办法在不进行赋值或伪造赋值的情况下进行 java 三元运算?

好的,所以当您编写这样的语句时:

    (bool1 && bool2) ? voidFunc1() : voidFunc2();

代码有两个明显的问题:

  1. 条件表达式1的第二个和第三个操作数不能调用 void 方法。参考:JLS 15.25

  2. 表达式不是语句,除非它是赋值表达式或方法调用或对象创建。参考:JLS 14.8

事实上,第二个问题是语法错误,我希望任何主流 Java 编译器都会报告它而不是第一个问题。只有当你做了这样的事情时,第一个问题才会暴露出来:

    SomeType dummy = (bool1 && bool2) ? voidFunc1() : voidFunc2();

或者

    gobble((bool1 && bool2) ? voidFunc1() : voidFunc2());

wheregobble是一个什么都不做的方法......除了“消耗”其参数的值。

AFAIK,没有可以接受原始表达的上下文。

但是,有一些方法可以包装void函数,以便可以在条件表达式中调用它们。这是一个:

 int dummy = (bool1 && bool2) ? 
     () -> {voidFunc1(); return 0;} : 
     () -> {voidFunc2(); return 0;};

1 - “条件表达式”是 Java 语言规范中用于此构造的主要术语。它在 Oracle Java 教程中被称为“三元条件运算符”。

于 2016-03-17T10:58:22.733 回答