在一个在线论坛上,有人提到Java的静态异常检查不是很好,导致可扩展性和版本控制问题。
我认为类函数的变化抛出了新的异常,打破客户端代码可能会归结为版本问题。但我不确定。
静态异常检查的可伸缩性问题是什么?
什么是动态异常检查?
答案 0 :(得分:3)
当程序员无法抛出适合该方法的异常时,Java中的已检查异常会导致可伸缩性问题。 (参见 Effective Java ,第43项:抛出适用于抽象的异常)。
懒惰的程序员倾向于在他们的方法的throws
子句中附加异常,而不考虑它们是否合适。因此,当您在应用程序体系结构中看起来越来越高时,方法会收集越来越多的异常。如果不小心,顶级方法可能会抛出十个或更多异常。
例如,在设计用于加密数据的方法中,可能抛出许多低级异常(例如IOException
,NoSuchAlgorithmException
,KeyNotFoundException
...)。没有必要将这些公开给API用户。相反,可能会抛出EncryptionFailed
异常,其中血腥细节存储在异常的cause
字段中。
我认为“动态异常检查”可能指的是捕获Throwable
或Exception
(其中一个根类),并根据某些外部刺激动态决定是否处理异常。例如:
List<Class<?>> exceptionTypes = new ArrayList<>();
exceptionTypes.add(IllegalArgumentException.class);
exceptionTypes.add(IOException.class);
try {
// do something
} catch (Exception e) {
if (exceptionTypes.contains(e.getClass())) {
e.printStackTrace();
}
}
注意:上面的例子只是一个例子。但想象一下,IDE代表用户执行代码,并允许他们选择他们希望捕获的异常类。
答案 1 :(得分:0)
我认为动态异常检查只是在运行时触发异常的另一个名称。
虽然我相信静态异常检查,但静态异常检查的Java方式确实存在涉及接口实现的问题。
说,我们有IParser
。它的方法parse()
可能会抛出哪些适当的例外?可能SyntaxErrorException
。现在我们希望以这种方式使用ServerResponseParserFromURL
:
class ServerResponseParserFromURL implements IParser { .... };
....
try {
IParser parser = new ServerResponseParser(new URL("http://example.com/test.htm"));
parser.parse();
....
}
问题在于此问题 - IParser
的实施可能会触发NoRouteToHostException
。所以我们不能使用漂亮而简洁的形式,需要回退到长形式:
class ServerResponseParser implements IParser { .... };
....
try {
String response = getServerResponse(new URL("http://example.com/test.htm"));
IParser parser = new ServerResponseParser(response);
parser.parse();
....
}
如您所见,实际上,我们IParser
为IStringParser
,而非通用IParser
。
虽然在这种特殊情况下可能是可以容忍的,但是当我们想要提供IParser
作为函数f
的参数之一时,它会使事情变得复杂。比如,为了能够解析网址标识的服务器的响应,我们不能只提供ServerResponseParser
对象和网址 - 我们需要找到一种方法将getServerResponse
方法提供给f
。< / p>