方法的返回对象抛出异常未进行处理,如何修复?

huangapple go评论81阅读模式
英文:

return object of the method throws exception does not handle, how to fix it?

问题

我已经创建了一个不可变类,实现了关于矩阵操作的责任,它的构造函数在遇到无效输入时会抛出异常。

public class Matrix {
    public Matrix(int[][] matrix) throws Exception {
        if (!isValid(matrix))
            throw new Exception("Bad Matrix");
        // 做一些操作
        // 做一些操作
        // 做一些操作
    }

    public Matrix transpose() {
        int[][] transposeMatrix = new int[column][row];
        // 做一些操作
        // 做一些操作
        // 做一些操作

        try {
            return new Matrix(transposeMatrix);
        } catch (Exception e) {
            // 处理异常
            e.printStackTrace();
        }
        // 在异常情况下返回什么?
    }
}

在transpose方法中,想要实例化Matrix类的一个新实例,显然这个方法负责处理异常,这就是问题所在,我不知道如何返回一个Matrix类的实例。

英文:

I have made an immutable class that implements the responsibilities about Matrix operations
its constructor throws an exception in confronting with invalid input

    public Class Matrix{
      public Matrix(int[][] matrix) throws Exception {
        if (!isValid(matrix))
          throw new Exception("Bad Matrix");
        sth();
        sth();
        sth();
      }


	  public Matrix transpose() {
        int[][] transposeMatrix = new int[column][row];
        sth();
        sth();
        sth();

	    try {
	 	    return new Matrix(transposeMatrix);
	    } catch (Exception e) {
		    // TODO Auto-generated catch block
		    e.printStackTrace();
	    }
     }
  }

in transpose method, a new instance of the Matrix class wants to be instantiated ,it's obvious that this method is responsible to handle the exception and this is the problem now I don't know how to return an instance of Matrix

答案1

得分: 3

问题在于你在构造函数中抛出了Exception。在构造函数中抛出和/或声明Exception几乎总是一个非常糟糕的想法

在这种情况下,最好抛出一个特定的未经检查的异常。要么声明自己的异常类,要么抛出现有的异常类。IllegalArgumentException将是一个不错的选择。

由于IllegalArgumentException是未经检查的异常,你不需要在Matrix构造函数的签名中声明它,也不需要在每次使用构造函数时都要“捕获或声明”它。


关于如果无法构造一个Matrix应该如何返回它,有两个直接的<sup>1</sup>答案:

  1. 不要捕获异常。让它传播到调用者...这个调用者在第一次提供了无效的输入。

  2. 返回一个null。注意,这必须在调用构造函数的代码中完成,因为构造函数不能返回null

然而,返回null会导致其他问题:

  • 如果调用(例如)transpose的调用者不检查调用的结果并采取适当的措施,这很可能会导致空指针异常。

  • 如果调用确实进行了检查,没有任何解释说明为什么结果是null。实际上,您可能在异常消息中包含的任何解释都将被丢弃(或作为堆栈跟踪转储到日志等)因此没有任何方法告诉最终用户...关于他们的错误输入。


<sup>1 - 还有第三种方法。实现一种表示Matrix无效的方式。例如,您可以声明Matrix的子类,并将其称为InvalidMatrix。该子类的某些方法将引发异常;例如“您无法转置无效的矩阵”。这还将涉及使用工厂方法,因为new操作无法根据参数创建不同类的实例。<br>
可以说,这违反了LSP,因为无法将InvalidMatrix用作真正的矩阵。但也可以说,它不违反 LSP,因为任何Java方法或构造函数都可以隐式抛出未经检查的异常。无论如何,这是一个务实的解决方案。<br>
请注意,在标准的Java SE类库中有这种类型的示例。例如,Collections中的unmodifiableList方法(javadoc)创建一个List实例,如果尝试修改它,将抛出UnsupportedOperationException异常。</sup>

英文:

The problem is that you are throwing Exception in the constructor. Throwing and / or declaring Exception is almost always a really bad idea.

In this case, it is better to throw a specific unchecked exception. Either declare your own exception class, or throw an existing one. IllegalArgumentException would be a good choice.

Since IllegalArgumentException is unchecked, you won't need to declare it in your Matrix constructor's signature, and you won't need to "catch or declare" it everywhere you use the constructor.


As to how you should return a Matrix if you can't construct it. There are two straightforward<sup>1</sup> answers:

  1. Don't catch the exception. Let it propagate to the caller ... which provided the invalid input in the first place.

  2. Return a null. Note this must be done in the code that calls the constructor, since a constructor cannot return null.

HOWEVER, returning null leads to other problems:

  • If the caller of (say) transpose doesn't check the result of the call, and act appropriately, this is liable to lead to NullPointerException down the track.

  • If the call does check, there is nothing explaining why the result is null. Indeed, any explanation that you might have included in the exception message will have been discarded (or dumped into the log, etc as a stacktrace) so that there is nothing to tell the end user ... about their bad input.


<sup>1 - There is a third approach too. Implement a way to represent an invalid matrix as a Matrix instance. For example you could declare a subclass of Matrix and call it InvalidMatrix. Some of the methods of this subclass would raise exceptions; e.g. "you cannot transpose an invalid matrix". This would also entail using a factory method, since the new operation cannot create instances of different classes depending on the arguments.<br>
It could be argued that this violates LSP since an InvalidMatrix cannot be used as a real matrix. But it could also be argued that it doesn't violate LSP, since any Java method or constructor can implicitly throw an unchecked exception. Either way, it is a pragmatic solution.<br>
Note that there examples of this kind of thing in the standard Java SE class library. For instance the unmodifiableList method in Collections (javadoc) creates a List instance that throws an UnsupportedOperationException if you try to modify it.</sup>

答案2

得分: 0

有一些语句可以在 catch 块中使用,第一种是抛出运行时异常(RuntimeException),第二种是返回空矩阵(Matrix),第三种是返回空(null);

  1. throw new RuntimeException();

  2. return new Matrix(new int[0][0]);

  3. return null;

英文:

There are some statements you can use in the catch block, 1st is throwing Runtime Exception, 2nd is returning empty matrix and 3rd is returning null;

  1. throw new RuntimeException();

  2. return new Matrix(new int[0][0]);

  3. return null;

huangapple
  • 本文由 发表于 2020年10月17日 13:02:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/64399176.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定