【问题标题】:How can I throw a general exception in Java?如何在 Java 中抛出一般异常?
【发布时间】:2011-08-04 13:51:07
【问题描述】:

考虑这个简单的程序。该程序有两个文件:

文件 Vehicle.java

class Vehicle {
    private int speed = 0;
    private int maxSpeed = 100;

    public int getSpeed()
    {
        return speed;
    }

    public int getMaxSpeed()
    {
        return maxSpeed;
    }

    public void speedUp(int increment)
    {
        if(speed + increment > maxSpeed){
            // Throw exception
        }else{
            speed += increment;
        }
    }

    public void speedDown(int decrement)
    {
        if(speed - decrement < 0){
            // Throw exception
        }else{
            speed -= decrement;
        }
    }
}

文件 HelloWorld.java

public class HelloWorld {

    /**
     * @param args
     */
    public static void main(String[] args) {

        Vehicle v1 = new Vehicle();
        Vehicle v2 = new Vehicle();

            // Do something

            // Print something useful, TODO
        System.out.println(v1.getSpeed());
    }

}

正如您在第一堂课中看到的,我添加了一条注释(“// throw exception”),我想在其中抛出异常。我是否必须为异常定义自己的类,还是可以使用 Java 中的一些通用异常类?

【问题讨论】:

  • 您可能会考虑根本不抛出异常,而只是将速度设置为零/最大值。为什么要惩罚不知道确切汽车行驶速度的呼叫者以停止/加速它?
  • 考虑将speedDown 重命名为slowDown
  • @dlev:同意,但这是代码设计的问题。您提出的行为符合正常汽车行为:加速到极限最高速度并减速到完全停止。
  • 来自 C# 背景,我和 Richard 有同样的问题,到目前为止似乎没有一个回答能明确回答。在 C# 中,您不必从 Exception 派生新类。您可以简单地“抛出新异常(消息);”例如,并在将捕获异常的块中对其进行一般处理。我仍在开发我的第一个 Java 应用程序 :-) 但从文档中的内容来看,Java 在异常方面几乎相同。

标签: java exception


【解决方案1】:

您可以创建自己的异常类:

public class InvalidSpeedException extends Exception {

  public InvalidSpeedException(String message){
     super(message);
  }

}

在您的代码中:

throw new InvalidSpeedException("TOO HIGH");

【讨论】:

    【解决方案2】:

    你可以使用 IllegalArgumentException:

    public void speedDown(int decrement)
    {
        if(speed - decrement < 0){
            throw new IllegalArgumentException("Final speed can not be less than zero");
        }else{
            speed -= decrement;
        }
    }
    

    【讨论】:

    • 查看我对之前类似答案的评论。另外,请注意使用 RuntimeExceptions,因为 throwing 方法没有声明它们。
    • Direct link to Vlad's comment(回答问题)。
    【解决方案3】:

    好吧,有很多异常要抛出,但这里是抛出异常的方法:

    throw new IllegalArgumentException("INVALID");
    

    另外,是的,您可以创建自己的自定义异常。

    关于异常的说明。当您抛出异常(如上)并捕获异常时:可以访问您在异常中提供的 String 抛出 getMessage() 方法。

    try{
        methodThatThrowsException();
    }catch(IllegalArgumentException e)
    {
      e.getMessage();
    }
    

    【讨论】:

    • 为什么这个参数是非法的?是否检查参数值?状态实际上不是非法的(speed &lt; 0) 所以他应该抛出一个 IllegalStateException 吗?
    • 好吧,对象的“状态”不是非法的,传递的参数是非法的。 (在这种情况下,递减变量是非法的,因为它大于速度本身)
    • 但是,您检查的是最终状态,而不是参数的值。这是误导。 如果 speed == 0 在调用speedDown 之前会怎样?
    • 我同意弗拉德的观点。仅当参数本身不正确时才应引发 IllegalArgumentException。这应该与对象的状态无关。但是 Mark 也是对的,它也不是 IllegalStateException...
    • @Fortega 对于这种情况,如果您不想创建自己的,恕我直言,这是最好的选择。
    【解决方案4】:

    这实际上取决于您在捕获该异常后要如何处理它。如果您需要区分您的异常,那么您必须创建您的自定义Exception。否则你可以throw new Exception("message goes here");

    【讨论】:

    • Exception 被选中。我不确定这会不会有成效。
    • RuntimeException 如何更更有效率
    • 它不会让调用者处理代表编程错误的异常。
    【解决方案5】:

    最简单的方法是:

    throw new java.lang.Exception();
    

    但是,您的代码将无法访问以下行。所以,我们有两种方法:


    1. 在方法的底部抛出一个通用异常。
    2. 如果您不想执行 1,请引发自定义异常。

    【讨论】:

      【解决方案6】:

      Java 有大量针对不同场景的内置异常。

      在这种情况下,你应该抛出一个IllegalArgumentException,因为问题是调用者传递了一个错误的参数。

      【讨论】:

      • 一个 IllegalArgumentException 应该只在不适当的参数的情况下被抛出,而不是在适当的参数导致某处溢出的情况下。所以我会抛出一个 IllegalArgumentException 以防出现负参数和超过最大速度时的自定义异常。
      【解决方案7】:

      您可以定义自己的异常类扩展 java.lang.Exception(用于已检查的异常 - 这些必须被捕获),或扩展 java.lang.RuntimeException - 这些异常不必被捕获。

      另一种解决方案是查看 Java API 并找到描述您的情况的适当异常:在这种特殊情况下,我认为最好的异常是 IllegalArgumentException

      【讨论】:

        【解决方案8】:

        这取决于。您可以抛出更一般的异常,或更具体的异常。对于更简单的方法,更一般的异常就足够了。如果方法很复杂,那么抛出更具体的异常是可靠的。

        【讨论】:

          猜你喜欢
          • 2019-01-07
          • 1970-01-01
          • 2010-10-03
          • 1970-01-01
          • 2016-08-10
          • 2021-10-05
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多