为什么Java自定义异常UniqueValueException未被重新抛出与捕获?
问题根因
你的checkCustomerUniqueValues方法内部已经将抛出的UniqueValueException捕获消化,没有向上重新抛出,因此上层addCustomer根本接收不到该异常,自然会继续执行后续的写入逻辑。
查看checkCustomerUniqueValues代码可以看到对应问题:
catch (UniqueValueException e) { e.printStackTrace(); // 此处仅打印了异常栈,没有重新抛出,异常到此终止 }
执行完catch块后方法会正常返回,对于addCustomer来说checkCustomerUniqueValues调用是正常结束的,因此会继续向下执行写入文件的流程。
修复方案
1. 调整checkCustomerUniqueValues的异常处理逻辑
推荐直接移除该方法内的UniqueValueException捕获分支,让业务异常自然向上抛出:
public static void checkCustomerUniqueValues(Customer c) throws UniqueValueException{ Scanner inFileStream = null; String custID = ""; String name = ""; float creditBalance = 0; String telephone = ""; String address = ""; try { inFileStream = new Scanner(new File("Digicel_Customers.txt")); while (inFileStream.hasNext()) { custID = inFileStream.next(); name = inFileStream.next(); creditBalance = inFileStream.nextFloat(); telephone = inFileStream.next(); address = inFileStream.nextLine(); if (custID.equals(c.getCustID())) { throw new UniqueValueException("Customer ID already exists."); } else if(telephone.equals(c.getTelephone().toString())){ throw new UniqueValueException("Telephone number already in use."); } } } // 移除UniqueValueException的捕获分支 catch (FileNotFoundException e) { e.printStackTrace(); throw new RuntimeException("读取客户文件失败", e); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("校验客户唯一性出现未知错误", e); } finally{ if(inFileStream != null) { try { inFileStream.close(); }catch(Exception e) { System.err.println("\nAn unexpected error occured."); } } } }
如果你需要在该方法内打印异常栈,也可以保留捕获分支并补充重新抛出的逻辑:
catch (UniqueValueException e) { e.printStackTrace(); throw e; // 补充该行重新抛出业务异常 }
2. 修复AdminGui的异常提示逻辑
当前AdminGui的异常捕获分支中弹出的是默认值为空的returnString,用户看不到具体错误,修改为读取异常的提示信息:
catch(UniqueValueException e1){ JOptionPane.showMessageDialog(parentFrame,e1.getMessage(),"Form Error",JOptionPane.ERROR_MESSAGE); }
3. 可选优化:修复addCustomer的异常捕获逻辑
当前addCustomer最外层的catch(Exception e)会捕获所有异常并返回错误字符串,你声明的throws UniqueValueException实际无效,上层永远接收不到该异常。如果要让上层能捕获业务异常,需要调整外层catch逻辑放过UniqueValueException:
// 放在原有异常捕获的最前面 catch(UniqueValueException e){ throw e; // 优先抛出业务异常 } catch(Exception e) { return("\nAn unexpected error occured."); }
修改完成后,校验到重复值时抛出的异常就能正常传递到上层,不会再执行后续的写入逻辑。
内容的提问来源于stack exchange,提问作者Ashley
相关产品推荐
相关产品推荐

