【问题标题】:Throw exceptions without using if - Java不使用 if 就抛出异常 - Java
【发布时间】:2019-08-08 05:35:53
【问题描述】:

有没有办法在你的函数中抛出一个异常而不使用 Java 中的 if 语句? 例如,如果一个整数小于 0,我想抛出一个异常,但是在检查那个特定条件时,我不想使用 if(或 switch)语句。

【问题讨论】:

  • 为什么?这是一个非常人为的要求,没有任何实际理由。
  • 在你告诉你不想使用 if 语句的同一个句子中,你暗示使用一个:“当检查那个特定条件时”......这对 if 语句尖叫,不不是吗?
  • 你可以做一些类似的事情和assert一些变量状态。
  • 可以使用三元运算符。如果您使用的是 java 8+,则为谓词
  • 如果我理解正确,当整数小于 0 时,您直接想抛出异常,而不用检查整数运行的额外代码。那是不可能的。我认为您唯一能做的就是一个额外的线程,您可以在其中注册所有整数,然后在该线程中使用 if 语句在 while(true) 循环中检查它们

标签: java if-statement exception throw


【解决方案1】:

可以这样做,当然,但是为什么呢?

public static void checkNegative(int n) {
    try {
        int[] a = new int[n];
    } catch (NegativeArraySizeException e) {
        throw new IllegalArgumentException();
    }
}

如果n < 0,上述方法将抛出IllegalArgumentException(或您想要的任何其他异常),如果0 <= n < 2^31 - 1,则不会执行任何操作。但可以肯定的是,在创建数组的代码中某处if,这是隐含的。

您还可以使用assert 来检查一个条件,如果验证的表达式是false,它将抛出一个AssertionError - 只要启用了断言:

assert n >= 0;

当然,您可以在显式验证条件的情况下抛出异常,但大多数时候您希望在抛出异常之前检查一些内容。

public static void throwForTheHeckOfIt() {
    throw new NumberFormatException();
}

你怎么知道你需要调用上面的方法,而不先检查一个条件?

【讨论】:

  • “不,你不能以这种方式抛出任意异常” 如果你捕捉到 NegativeArraySizeException 并在 catch 块中抛出所需的任意异常,则可以.
  • @Andreas 你是对的,当然!我更新了我的答案。
  • "并且如果 n >= 0" 则什么也不做 ...当然,除非 n 足够大以至于 VM 无法分配数组
  • @CupawnTae 这是一个很好的收获:)。我很惊讶人们如何努力完美地回答这样一个……荒谬的问题!
【解决方案2】:

如果我从字面上理解你的问题,这里有一个答案。没有 if 语句,也没有 switch。

public class NoIf {

    static void f(int x) throws Exception {
        while (x < 0) {
            throw new Exception();
        }
    }

    public static void main(String[] args) throws Exception {
        System.out.println("Trying with 1...");
        f(1);
        System.out.println("Trying with -1...");
        f(-1);
        System.out.println("Done!");
    }

}

从他更优雅的回答中引用 Óscar López:但为什么呢?

【讨论】:

  • 我喜欢这个 - 它处理比new int[n] 更大的数字,可以适应非整数,并且不需要启用断言
【解决方案3】:

你可以用三元运算符做一个技巧,但这就像 if 语句:

public class Task3 {
    public static void main(String[] args) throws Exception {
        someMethodReturningString(false);
    }

    private static String someMethodReturningString(boolean condition) throws Exception {
        return condition ? "true" : methodThrowingException();
    }

    private static String methodThrowingException() throws Exception {
        throw new Exception("Exception");
    } 
}

但这只是一个技巧。您不能在三元运算符中直接使用 throw 关键字,因为三元运算符应始终返回一个值。但是您始终可以在三元运算符中调用返回所需类型的方法。

我真的不知道你什么时候会需要这样的东西。我认为 if-else 构造是最好的,因为您经常希望在“如果”出现问题或满足某些“条件”时抛出异常。

【讨论】:

  • 不幸的是,您不能从 Java 中的三元语句中抛出异常。这行不通
  • 这行得通,我刚刚编译了它。你不能像这样明确地抛出它:条件? “真”:抛出新异常();这就是为什么我使用一种技巧来创建一个返回值并引发异常的方法。我也在我的回答中写过。
  • 啊,我明白了。对不起,我的错
【解决方案4】:

我猜你的意思是这样的:

-一次注册整数

-当这些整数之一变为0时抛出异常

为这个问题编写了这个类:

import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;

class IntegerChecker {
    private ArrayList<AtomicInteger> list = new ArrayList<>();

    IntegerChecker() {
        Thread t = new Thread(() -> {
            AtomicBoolean error = new AtomicBoolean(false);
            while (!error.get()) {
                list.forEach(integer -> {
                    if (integer.get() == 0) {
                        error.set(true);
                        throw new RuntimeException();
                    }
                });
            }
        });
        t.start();
    }

    void addInt(AtomicInteger i) {
        list.add(i);
    }
}

要测试它,请使用这个带有 JFrame 的小程序:

public static void main(String[] args) {
    AtomicInteger i = new AtomicInteger(5);

    IntegerChecker checker = new IntegerChecker();
    checker.addInt(i);

    JFrame frame = new JFrame();
    JButton button = new JButton("Click me to throw exception");
    button.addActionListener(e -> i.set(0)); //If you click the button, the integer will turn to 0 which triggers the other class
    frame.getContentPane().add(button);
    frame.pack();
    frame.setVisible(true);
}

(可能是我对帖子的解释有点过分,但如果你的意思不是我想的那样,我看不出有什么理由问这样的问题)

【讨论】:

    【解决方案5】:

    您可以使用三元运算符将不同类型的异常分配给变量,然后抛出异常。

    然后,您可以通过捕获特定异常并重新抛出它来处理数字小于 0 的情况。另一个 Exception 应该有一个空的 catch。

    int number = 0;
    
    RuntimeException result = number < 0 ? new NumberFormatException() : new RuntimeException();
    
    try {
        throw result;
    } catch (NumberFormatException e) {
        throw e;  
    } catch (RuntimeException e) {
        // Do nothing
    } 
    

    【讨论】:

    • 谢谢!这是我需要的最平易近人的解决方案!
    • @MariaPascu 三元运算符只是 IF 的不同语法,它还检查布尔条件,唯一的区别是它返回一个值。也许下次你在为什么你需要你所问的问题中解释一下会有所帮助。
    【解决方案6】:

    有没有办法在你的函数中抛出一个异常而不使用 Java 中的 if 语句?

    是的。一般来说,throw 语句不需要if 语句。

    例如,如果一个整数小于0,我想抛出一个异常

    请仔细阅读您在此处写的内容。由于您只想在某个条件为真时抛出异常,因此您必须使用 if 语句。一般来说,您的代码应该遵循您用来描述它的词语。

    但在检查特定条件时,我不想使用 if(或 switch)语句。

    这是不可能的。在 Java 中检查条件需要 if 语句。

    【讨论】:

      【解决方案7】:

      Spring 框架有一个通用的简单实现:

      import org.springframework.util.Assert;
      
      Assert.isTrue(someCondition,"some condition is not true.");
      

      实现:

      public static void isTrue(boolean expression, String message) {
              if (!expression) {
                  throw new IllegalArgumentException(message);
              }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-07-23
        • 1970-01-01
        • 2013-03-14
        • 1970-01-01
        • 2021-05-11
        • 2012-05-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多