You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 08:07:34