"Unhandled exception type" 当在紧凑结构中抛出异常时(StringConverter 情况)
"Unhandled exception type" when Throwing exception inside a compact structure (StringConverter case)
我相信这一定是我的语法无知。
我想创建一个方法来创建 return StringConverter 对象。问题是这个对象必须在其中一个方法中抛出异常。而且我相信我一直在失败,因为语法。
我有两个例子,最后一个编译得很好。
查看第一种方法,Eclipse 显示“未处理的异常类型 CharConversionException”:
public static StringConverter<String> creditoDebito() {
return new StringConverter<String>() {
@Override
public String fromString(String arg0) {
switch(arg0.charAt(0)) {
case 'D':
case 'd':
return "Débito";
default:
throw new CharConversionException();
}
}
};
}
看看其中一个成功的例子,它编译得很好:
public static StringConverter<BigDecimal> numberCellConverter(){
return new StringConverter<BigDecimal>() {
@Override
public BigDecimal fromString(String arg0) {
Pattern patternDefault = Pattern.compile("\d*");
Matcher matcher = patternDefault.matcher(arg0);
if(matcher.find()) {
return new BigDecimal(arg0);
}else {
throw new NumberFormatException();
}
}
};
}
这两种情况有什么区别?为什么 NumberFormatException 可以编译而另一个不能?
异常不仅仅是一个有趣的名字。您不应该仅仅因为名称听起来含糊不清就使用异常。 CharConversionException 是关于字符集编码的问题,例如XML阅读;重点是,它扩展了 IOException,所以它是一种 'problem with an Input/Output channel',只是不适用于此处。创建您自己的异常类型,或使用一种更通用的异常类型,这些异常类型是有意设计的(通过阅读 javadoc 并检查继承),使其更加模糊。例如,IllegalArgumentException
可以在这里使用(如果参数不是以 D 或 d 开头,它显然是非法的?有点奇怪的方法)。
区别在于异常的种类。
在java中,throwables是checked,意思是,一个方法需要捕获它抛出的所有异常,除非它明确规定它自己抛出这个。因此,这不会编译:
public void test() {
throw new IOException();
}
而这样做:
public void test() throws IOException {
throw new IOException();
}
请注意,通过调用一个声明它抛出某些东西的方法,您继承了这个 'catch it or declare that you rethrow it'。因此,这不会编译:
public void test2() {
test(); // declared to `throws IOException`
}
而这样做:
public void test2() throws IOException {
test();
}
请注意 public static void main(String[] args)
被允许(通常应该!)声明为 throws Exception
.
Java 中有另一条规则解释了为什么 NumberFormatException 获得通过:所有方法都假定为 throws RuntimeException, Error
(例如,可以抛出 RuntimeException 和 Error 实例),无论您是否编写此与否。
检查 NumberFormatException
的层次结构:它是 RuntimeException 的特化,因此,本质上所有方法都声明为 throws
是。 CharConversionException extends IOException extends Exception extends Throwable - 该列表中没有任何内容是 RuntimeException 或 Error,因此不允许通过。
更糟糕的是,如果您从超类型实现一个方法(例如此处;您正在覆盖 public String fromString(String arg)
方法),您不能只在声明中添加新方法。毕竟,您正在编写一种 StringConverter,这意味着任何人都可以将您新定义的 class 的实例视为 StringConverter,而 StringConverter 的 fromString 方法没有声明它,因此,您被卡住了。
幸运的是,正如我所说,CharConversionException 不合适,但 IllegalArgumentException 可能合适,并且 IllegalArgumentException 未被选中(它扩展了 RuntimeException,因此,您可以随意抛出它,因为所有方法都被默认为这样做)。
我相信这一定是我的语法无知。
我想创建一个方法来创建 return StringConverter 对象。问题是这个对象必须在其中一个方法中抛出异常。而且我相信我一直在失败,因为语法。
我有两个例子,最后一个编译得很好。
查看第一种方法,Eclipse 显示“未处理的异常类型 CharConversionException”:
public static StringConverter<String> creditoDebito() {
return new StringConverter<String>() {
@Override
public String fromString(String arg0) {
switch(arg0.charAt(0)) {
case 'D':
case 'd':
return "Débito";
default:
throw new CharConversionException();
}
}
};
}
看看其中一个成功的例子,它编译得很好:
public static StringConverter<BigDecimal> numberCellConverter(){
return new StringConverter<BigDecimal>() {
@Override
public BigDecimal fromString(String arg0) {
Pattern patternDefault = Pattern.compile("\d*");
Matcher matcher = patternDefault.matcher(arg0);
if(matcher.find()) {
return new BigDecimal(arg0);
}else {
throw new NumberFormatException();
}
}
};
}
这两种情况有什么区别?为什么 NumberFormatException 可以编译而另一个不能?
异常不仅仅是一个有趣的名字。您不应该仅仅因为名称听起来含糊不清就使用异常。 CharConversionException 是关于字符集编码的问题,例如XML阅读;重点是,它扩展了 IOException,所以它是一种 'problem with an Input/Output channel',只是不适用于此处。创建您自己的异常类型,或使用一种更通用的异常类型,这些异常类型是有意设计的(通过阅读 javadoc 并检查继承),使其更加模糊。例如,IllegalArgumentException
可以在这里使用(如果参数不是以 D 或 d 开头,它显然是非法的?有点奇怪的方法)。
区别在于异常的种类。
在java中,throwables是checked,意思是,一个方法需要捕获它抛出的所有异常,除非它明确规定它自己抛出这个。因此,这不会编译:
public void test() {
throw new IOException();
}
而这样做:
public void test() throws IOException {
throw new IOException();
}
请注意,通过调用一个声明它抛出某些东西的方法,您继承了这个 'catch it or declare that you rethrow it'。因此,这不会编译:
public void test2() {
test(); // declared to `throws IOException`
}
而这样做:
public void test2() throws IOException {
test();
}
请注意 public static void main(String[] args)
被允许(通常应该!)声明为 throws Exception
.
Java 中有另一条规则解释了为什么 NumberFormatException 获得通过:所有方法都假定为 throws RuntimeException, Error
(例如,可以抛出 RuntimeException 和 Error 实例),无论您是否编写此与否。
检查 NumberFormatException
的层次结构:它是 RuntimeException 的特化,因此,本质上所有方法都声明为 throws
是。 CharConversionException extends IOException extends Exception extends Throwable - 该列表中没有任何内容是 RuntimeException 或 Error,因此不允许通过。
更糟糕的是,如果您从超类型实现一个方法(例如此处;您正在覆盖 public String fromString(String arg)
方法),您不能只在声明中添加新方法。毕竟,您正在编写一种 StringConverter,这意味着任何人都可以将您新定义的 class 的实例视为 StringConverter,而 StringConverter 的 fromString 方法没有声明它,因此,您被卡住了。
幸运的是,正如我所说,CharConversionException 不合适,但 IllegalArgumentException 可能合适,并且 IllegalArgumentException 未被选中(它扩展了 RuntimeException,因此,您可以随意抛出它,因为所有方法都被默认为这样做)。