英文:
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>答案:
-
不要捕获异常。让它传播到调用者...这个调用者在第一次提供了无效的输入。
-
返回一个
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:
-
Don't catch the exception. Let it propagate to the caller ... which provided the invalid input in the first place.
-
Return a
null
. Note this must be done in the code that calls the constructor, since a constructor cannot returnnull
.
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);
-
throw new RuntimeException();
-
return new Matrix(new int[0][0]);
-
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;
-
throw new RuntimeException();
-
return new Matrix(new int[0][0]);
-
return null;
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论