Scala中出现ExceptionInInitializerError而非预期自定义异常问题
问题原因
你遇到的ExceptionInInitializerError是Scala App trait的特性导致的:当object继承App时,其顶级作用域中的代码(包括你写的println(PocketCalculator1.divide(10, 0)))会被编译到类的静态初始化方法(<clinit>)中执行。如果这段初始化代码抛出异常,JVM会将原始异常包装成ExceptionInInitializerError抛出,而非直接抛出你的自定义异常。
你的讲师未出现该问题,大概率是他将调用代码放在了显式定义的main方法中,而非依赖App trait的自动初始化逻辑。
解决方案
有两种简单的修正方式:
方式1:放弃App trait,显式定义main方法
移除extends App,手动实现main方法,让代码在标准的入口方法中执行:
package lectures.part2oop object SO { class OverflowException1 extends RuntimeException class UnderflowException1 extends RuntimeException class MathCalculationException1 extends RuntimeException("division by zero") object PocketCalculator1 { def add(x: Int, y: Int): Int = { val result = x + y if (x > 0 && y > 0 && result < 0) throw new OverflowException1 else if (x < 0 && y < 0 && result > 0) throw new UnderflowException1 else result } def subtract(x: Int, y: Int): Int = { val result = x - y if (x > 0 && y < 0 && result < 0) throw new OverflowException1 else if (x < 0 && y > 0 && result > 0) throw new UnderflowException1 else result } def multiply(x: Int, y: Int): Int = { val result = x * y if (x > 0 && y > 0 && result < 0) throw new OverflowException1 else if (x < 0 && y < 0 && result < 0) throw new OverflowException1 else if (x > 0 && y < 0 && result > 0) throw new UnderflowException1 else if (x < 0 && y > 0 && result > 0) throw new UnderflowException1 else result } def divide(x: Int, y: Int): Int = { if (y == 0) throw new MathCalculationException1 else x / y } } def main(args: Array[String]): Unit = { println(PocketCalculator1.divide(10, 0)) } }
方式2:保留App trait,重写main方法
继续继承App,但显式重写main方法,将调用代码放在该方法内:
package lectures.part2oop object SO extends App { class OverflowException1 extends RuntimeException class UnderflowException1 extends RuntimeException class MathCalculationException1 extends RuntimeException("division by zero") object PocketCalculator1 { def add(x: Int, y: Int): Int = { val result = x + y if (x > 0 && y > 0 && result < 0) throw new OverflowException1 else if (x < 0 && y < 0 && result > 0) throw new UnderflowException1 else result } def subtract(x: Int, y: Int): Int = { val result = x - y if (x > 0 && y < 0 && result < 0) throw new OverflowException1 else if (x < 0 && y > 0 && result > 0) throw new UnderflowException1 else result } def multiply(x: Int, y: Int): Int = { val result = x * y if (x > 0 && y > 0 && result < 0) throw new OverflowException1 else if (x < 0 && y < 0 && result < 0) throw new OverflowException1 else if (x > 0 && y < 0 && result > 0) throw new UnderflowException1 else if (x < 0 && y > 0 && result > 0) throw new UnderflowException1 else result } def divide(x: Int, y: Int): Int = { if (y == 0) throw new MathCalculationException1 else x / y } } override def main(args: Array[String]): Unit = { println(PocketCalculator1.divide(10, 0)) } }
修改后运行代码,就会直接抛出你定义的MathCalculationException1,不再出现包装后的异常。
内容的提问来源于stack exchange,提问作者BernardA
相关产品推荐
相关产品推荐

