Java。将短的 "ifelse "与简单的 "return "和尾部的 "throw "折叠成一个 "return"。

问题描述 投票:2回答:4

这里有一些代码,多少是 "日线 "模式。

public static Value getValue() {    
    if ( cond1 ) {
        return val1;
    }
    if ( cond2 ) {
        return val2;
    }
    if ( cond3 ) {
        return val3;
    }
    throw new AnyException();
}

乍一看,它似乎可以折叠成一个单一的... return 语句保留了这样的短路计算。

public static Value getValue() {    
    return cond1 ? val1 :
           cond2 ? val2 :
           cond3 ? val3 :
           throw new AnyException() // it could be a legal piece of code in Java
                                    // if the `throw` statement could be an expression
           ;
}

但是,这是不合法的,因为 throw 是一个语句关键字,而不是一个表达式。我试过使用通用方法来解决以下问题。

// Exceptions.java
// Just pretend to let the compiler think it's not an exception statement
public static <T, E extends Throwable> T exception(E ex) throws E {
    throw ex;
}

...
// Return.java
public static Value getValue() {    
    return cond1 ? val1 :
           cond2 ? val2 :
           cond3 ? val3 :
           Exceptions.<Value, AnyException>exception(new AnyException());
}

最后一行在 return 语句看起来很丑,因为

  • 冗长的语法和必要的类型参数化。
  • 静态导入指令不能在这里使用。

有没有一种优雅的方法可以让这段代码变得更漂亮一些?先谢谢你了。

(我还是必须使用Java 6)

EDIT。

好了,三年后,这个功能是超乎寻常地实现了对。C# 7.0. 我觉得它真的很有用,很自然,而且不复杂。例子。

public string GetFirstName()
{
    var parts = Name.Split(" ");
    return parts.Length > 0
        ? parts[0]
        : throw new InvalidOperationException("No name!");
}

幸运的C#家伙。

java syntax type-inference short-circuiting
4个回答
4
投票

如果你使用 exception 外的条件操作符,那么类型推理就会做正确的事情。在这里,你可以不指定类型参数,而直接将结果降格为 Value,无论是当地的 exception():

return cond1 ? val1 :
       cond2 ? val2 :
       cond3 ? val3 :
       (Value)exception(new AnyException());

或全局性的,对于整个条件表达式。

return (Value) (
       cond1 ? val1 :
       cond2 ? val2 :
       cond3 ? val3 :
       exception(new AnyException()));

从优雅的角度来说,这仍然不是什么好东西,但我认为它有很大的作用。请注意,在这种情况下,你可以为以下内容设置静态导入 exception().


2
投票

如果你重新排列你的线条,并添加另一个 if 语句,你可以将行数减少到最小,同时仍有可读性的东西。

if(!(cond1 || cond2 || cond3)) throw new AnyException();
return cond1 ? val1 :
       cond2 ? val2 :
       cond3 ? val3;

我必须说,你把事情搞得太复杂了。可读的代码几乎总是比真正简洁的代码要好。在你的第一个例子中,我立刻明白了你要做什么。在你的第二个例子中,我实际上不得不集中精力。


2
投票

有另一种方法可以抛出一个没有属性的通用异常。

// Exceptions.java
// Just pretend to let the compiler think it's not an exception statement
public static <T> T exception(E ex, Class<T> tClass) {
    Thread.currentThread().stop(ex);
    return null;
}

...
// Return.java
public static Value getValue() {    
    return cond1 ? val1 :
           cond2 ? val2 :
           cond3 ? val3 :
           exception(new AnyException(), Value.class); // import static Exception
}

你也可以使用Unsafe.throwException(e)。


0
投票
int length = 1;
String s = "abc"

return (length == s.length())? length: length+1;

短手if else做返回函数。

© www.soinside.com 2019 - 2024. All rights reserved.