我正在尝试制作一个更干净的嵌套try catch块版本,并且在解决一个非常基本的异常问题。我正在做一个可以做得很好的计算器。但是,在此之前,它必须将用户输入作为字符串并将其转换为浮点数或整数。我通过简单地调用Java的内置parseInt和parseFloat函数来做到这一点。现在,我正在使用嵌套的try catch块来做到这一点:
String stringToParse = "1.0"
try{Integer.parseInt(stringToParse);}
catch(NumberFormatException n){
try{Float.parseFloat(stringToParse);}
catch(NumberFormatException n){
System.out.println(n)
}
}
这对我来说很麻烦,我宁愿有一个try块来收集错误,但不会立即进入catch块,而是执行整个try并在try执行之后捕获所有错误。我自己做了一个可运行的例子,展示了我的愿望:
String num = "1.0";
int i = 0;
ArrayList<Object> listofResults = new ArrayList<>();
ArrayList<Integer> listOfErrorIndices = new ArrayList<>();
try {
listofResults.add(Integer.parseInt(num));
i++;
listofResults.add(Float.parseFloat(num));
i++;
listofResults.add(Integer.parseInt(num));
} catch (NumberFormatException n) {
listOfErrorIndices.add(i);
}
for (Integer element:listOfErrorIndices) {
System.out.println(element);
//this currently prints out 0 and I want it to print out both 0 and
//2 so that it catches both errors.
}
我的计划是收集尝试中所有抛出的NumberFormatException
索引(i
)的列表。每次我尝试解析字符串时,都会将元素添加到resultsList
中。我的目标是使用这个理论上的try catch块来获取所有异常的索引,如果它们抛出错误,则将它们从resultsList
中删除。 TLDR;现在,上面的代码打印出0,而我希望它打印出0和2。基本上,与其使用嵌套的try catch块,我还使用列表理解和带有i的异常处理指标来删除错误结果并仅保留好结果。我不知道这是否可行,因此是这个问题。我看过“实现嵌套try catch块的更好方法”的问题,但是它对我没有用,因为它在delphi中提供了解决方案,我不知道它是如何工作的,甚至我也不知道它是如何工作的想要我的工作。起初我以为finally块可能是我需要的,但是只有在执行catch或没有异常后才尝试运行。我需要将catch块推迟到尝试完成之前的东西,而我想不到/找到能做到这一点的东西。
现在您可能会问,这到底是什么意思?很好地想象一下,如果您遇到上述问题,而不是使用两种方法来解析字符串,则需要10或100。很快,使用嵌套try catch块进行异常处理几乎是不可能的。我见过解决方案,其中catch块调用一个自定义异常方法,然后该方法至少要处理不良的格式。看起来像这样:
try{
//bad code
}
catch{
trysomethingelse();
}
trysomethingelse(){
//equally bad code
catch{
//ya done screwed up son
}
}
但是我不满意,因为这意味着您需要一百万个不同的方法名才能处理一个错误。试想一下,错误始终是相同的,您只需要尝试100种不同的字符串解析方法即可。如果您尝试将字符串转换为数字,它将始终是numberformatException,那么为什么仅针对同一错误就拥有一百万个catch块?我想尝试用一个理论上的catch块来做到这一点,它指定了一个在try块中发生多次的错误。
答案 0 :(得分:1)
您可以执行以下操作:
interface Parser {
Number parse(String);
}
class IntegerParser implements Parser {
@Override
public Number parse(String) {
// implementation here
}
}
class FloatParser implements Parser {
}
List<Parser> parsers = asList(new FloatParser(), new IntegerParser(), ...);
Number result = null;
List<NumberFormatException> exceptions = new ArrayList<>();
for (Parser parser : parsers) {
try {
result = parser.parse(stringToParse);
break;
} catch (NumberFormatException e) {
exceptions.add(e);
}
}
if (result != null) {
// parsed ok with some parser
// probably discard exceptions
} else {
// show exceptions from the list
}
答案 1 :(得分:1)
您建立一个解析器列表/数组,然后迭代该列表,捕获每个解析器的异常。
有了Java 8方法参考,这确实很容易。首先,定义一个validate()
功能接口,该接口允许引发异常:
function validate(){
var ddlIncome = document.getElementById("income");
var ddlExpence = document.getElementById("expense");
var selectedValueIncome = ddlIncome.options[ddlIncome.selectedIndex].value;
var selectedValueExpence = ddlExpence.options[ddlExpence.selectedIndex].value;
if (selectedValueIncome != "selectincome"){
document.getElementById("expense").disabled=true;
}
else if (selectedValueIncome != "selectexpence"){
document.getElementById("income").disabled=true;
}
}
接下来,构建您的解析器数组以尝试:
Parser
最后,一次尝试一个:
@FunctionalInterface
public interface Parser {
Object parse(String text) throws Exception;
}
现在您可以浏览结果:
Parser[] parsers = {
Integer::valueOf,
Double::valueOf,
BigInteger::new,
BigDecimal::new
};
输出
String text = "45.8";
Object[] results = new Object[parsers.length];
for (int i = 0; i < parsers.length; i++) {
try {
results[i] = parsers[i].parse(text);
} catch (Exception e) {
results[i] = e;
}
}
或将已解析的对象和异常放入两个不同的列表中。由你决定。
答案 2 :(得分:0)
尝试一下:
public static void test() {
final String num = "1.0";
final ArrayList<Object> listofResults = new ArrayList<>();
final java.util.function.Function<String, ?>[] parseMethods = new java.util.function.Function[3];
parseMethods[0] = Integer::parseInt;
parseMethods[1] = Float::parseFloat;
parseMethods[2] = Integer::parseInt;
int[] badIndeces = IntStream.range(0, parseMethods.length).map(i -> {
try {
listofResults.add(parseMethods[i].apply(num));
return -i-1;
} catch (NumberFormatException exc) {
return i;
}
}).filter(i -> i >= 0).toArray();
for (int element : badIndeces) {
System.out.println(element);
}
}