当前位置: 首页 > 知识库问答 >
问题:

为什么在某些情况下重新扔一个可扔的东西是合法的,而不需要声明?

饶德元
2023-03-14

我希望下面的代码在throw t;上引发一个编译时错误,因为main没有声明为throwthrowable,但它编译成功(在Java 1.7.0_45中),并生成您希望的输出,如果该编译时错误得到修复的话。

public class Test {
    public static void main(String[] args) {
        try {
            throw new NullPointerException();

        } catch(Throwable t) {
            System.out.println("Caught "+t);
            throw t;
        }
    }
}

如果throwable更改为exception,它也会进行编译。

这并不像预期的那样编译:

public class Test {
    public static void main(String[] args) {
        try {
            throw new NullPointerException();

        } catch(Throwable t) {
            Throwable t2 = t;
            System.out.println("Caught "+t2);
            throw t2;
        }
    }
}

这将编译:

public class Test {
    public static void main(String[] args) {
        try {
            throwsRuntimeException();

        } catch(Throwable t) {
            System.out.println("Caught "+t);
            throw t;
        }
    }

    public static void throwsRuntimeException() {
        throw new NullPointerException();
    }
}

这并不是:

public class Test {
    public static void main(String[] args) {
        try {
            throwsCheckedException();

        } catch(Throwable t) {
            System.out.println("Caught "+t);
            throw t;
        }
    }

    public static void throwsCheckedException() {
        throw new java.io.IOException();
    }
}
public class Test {
    public static void main(String[] args) throws java.io.IOException {
        try {
            throwsIOException();

        } catch(Throwable t) {
            System.out.println("Caught "+t);
            throw t;
        }
    }

    public static void throwsIOException() throws java.io.IOException {
        throw new java.io.IOException();
    }
}
public class Test {
    public static void main(String[] args) {
        try {
            try {
                throwsIOException();

            } catch(Throwable t) {
                System.out.println("Caught "+t);
                throw t;
            }
        } catch(java.io.IOException e) {
            System.out.println("Caught IOException (outer block)");
        }
    }

    public static void throwsIOException() throws java.io.IOException {
        throw new java.io.IOException();
    }
}

共有1个答案

周伟泽
2023-03-14

JLS 11.2.2(重点是地雷)对此作了规定:

抛出的表达式是catch子句C的final或实际上是final异常参数的throw语句可以抛出异常类E。iff:

>

  • E是声明C的try语句的try块可以抛出的异常类;而且

    这就是为什么他们会特地说出一个最终的或者实际上是最终的异常参数--如果您的示例中的t被重新分配,那么分析就会消失。

  •  类似资料:
    • 问题内容: 我希望下面的代码在上引发编译时错误,因为未声明为throw ,但编译成功(在Java 1.7.0_45中),并且如果编译时错误为,则会生成您期望的输出固定。 如果更改为,它也会编译。 不会按预期方式编译: 这样编译: 这不是: 这也可以编译: 一个更复杂的示例-被检查的异常由外部catch块捕获,而不是被声明为抛出。这样编译: 因此,当编译器可以确定捕获的异常始终合法地重新抛出时,似乎

    • 在Java理论上,您只能抛出。 这是语言允许的,并在类加载期间进行检查。但是如果您禁用类检查 然后,您可以运行一个抛出任何类(不是从派生的)的类(示例) 为什么? 为什么要这样设计...意味着一个允许抛出对象的虚拟机和一个必须过滤掉错误代码的验证器。好像有些代码可能是错误的。这不是代码,这是设计! 为什么?

    • 问题内容: 我已经在这个程序上工作了一段时间了,我的大脑被炸了。我可以向其他人寻求帮助。 我正在尝试制作一个程序来逐行读取文本文件,并且将每一行都制成一个,以便可以访问每个令牌。我究竟做错了什么? 我要戳一下眼球。我遇到了三个错误: 我究竟做错了什么? 问题答案: 在大多数情况下,当您使用Java使用I / O时,您必须处理IOException,这可能在您读/写甚至关闭流时随时发生。 您必须将敏

    • 问题内容: 传统观点认为,您只能抛出在Java 中扩展的对象,但是是否可以禁用字节码验证程序并让Java编译并运行抛出任意对象(甚至是原语)的代码? 我查找了JVM ,它将弹出操作数堆栈中的第一个objref。但是会检查所述引用是否指向运行时? 问题答案: 这取决于您的JVM实现。根据Java VM规范,如果对象不是,则它是未定义的行为。 objectref 必须 是引用类型,并且必须引用Thro

    • 问题内容: 我正在学习CopyOnWriteArrayList类。 复制新阵列的目的是什么? 是其他线程读取数组吗? 因此,如果系统具有高并发性,并且大多数线程的操作都在读取而不是写入,那么最好使用。 问题答案: 如该链接所述: CopyOnWriteArrayList是Java 5并发API中引入的并发Collection类,以及它在Java中流行的表亲。 工具列表界面类似,并且但它的一个线程安

    • 问题内容: 为什么 工作,但是 不是吗 问题答案: 为了理解这一点,让我们考虑一下编译器在两种可能性下每个步骤所做的事情。让我们开始: 编译器将‘4’转换为int。所以变成 然后编译器变成 ch是一个字符,编译器可以将54转换为字符,因为它可以证明转换没有损失。 现在让我们考虑第二个版本: ch在编译时没有已知值。因此,这成为 现在,编译器无法证明此(int)的结果在char范围内可存储。因此它