我希望下面的代码在上引发编译时错误throw t;
,因为main
未声明为throw Throwable
,但编译成功(在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();
}
}
一个更复杂的示例-被检查的异常由外部catch块捕获,而不是被声明为抛出。这样编译:
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();
}
}
因此,当编译器可以确定捕获的异常始终合法地重新抛出时,似乎有一种特殊情况允许重新抛出异常。这样对吗?JLS在哪里指定?还有其他类似的晦涩难解案例吗?
JLS
11.2.2
(重点是我)对此进行了介绍:
如果throw语句的抛出表达式是 catch子句C 的最终或有效的最终 异常参数 ,则可以抛出异常类E iff:
E是一个异常类,声明C的try语句的try块可以抛出该异常类;和
E是与C的任何可捕获异常类兼容的分配 ;和
(…)
换句话说,E
doc中引用的类型 是可以抛出 的类型,而不是捕获它的catch子句参数的类型( catchable异常类 )。它只需要在 分配
上与catch子句参数 兼容 ,但是在分析中不使用该参数的类型。
这就是为什么竭尽全力说出 最终或有效的最终异常参数的 原因-如果t
在您的示例中重新分配了 异常 ,则分析将超出预期范围。
我希望下面的代码在上引发一个编译时错误,因为没有声明为throw,但它编译成功(在Java 1.7.0_45中),并生成您希望的输出,如果该编译时错误得到修复的话。 如果更改为,它也会进行编译。 这并不像预期的那样编译: 这将编译: 这并不是:
问题内容: 为什么 工作,但是 不是吗 问题答案: 为了理解这一点,让我们考虑一下编译器在两种可能性下每个步骤所做的事情。让我们开始: 编译器将‘4’转换为int。所以变成 然后编译器变成 ch是一个字符,编译器可以将54转换为字符,因为它可以证明转换没有损失。 现在让我们考虑第二个版本: ch在编译时没有已知值。因此,这成为 现在,编译器无法证明此(int)的结果在char范围内可存储。因此它
我遇到了一个非常奇怪的问题,java线程正忙着等待。 我有一个线程忙于等待其他线程的静态变量的状态。假设忙碌等待的线程正在等待另一个线程的静态int变量达到某个值 如果我使用上面的代码,线程将被卡在忙等待中,不会跳出while循环,即使确实达到5。 但是,如果我使用其他代码,那么线程确实会跳出忙等待循环。有时,一旦达到5,其他时候会晚一点。但它会发生。对于我的特定示例,我将其用作“无意义的工作”
问题内容: 我正在学习CopyOnWriteArrayList类。 复制新阵列的目的是什么? 是其他线程读取数组吗? 因此,如果系统具有高并发性,并且大多数线程的操作都在读取而不是写入,那么最好使用。 问题答案: 如该链接所述: CopyOnWriteArrayList是Java 5并发API中引入的并发Collection类,以及它在Java中流行的表亲。 工具列表界面类似,并且但它的一个线程安
我想知道为什么java编译器允许在方法声明中抛出,而方法永远不会抛出异常。因为“throws”是处理异常的一种方式(告诉调用方处理它)。 因为有两种处理异常的方法(抛出和try/catch)。在try/catch中,它不允许捕获try块中未抛出的异常,但它允许在不抛出异常的方法中抛出。
我用Kotlin和Jongo来访问MongoDB。Jongo使用Jackson来序列化/反序列化对象,以便从MongoDB中保存和读取它们。我使用Jackson-Kotlin模块来帮助使用构造函数序列化Kotlin数据类。 下面是一个序列化良好的数据类的示例: 下面是一个未能反序列化的类似类的示例: Jongo抛出以下异常,因为Jackson反序列化失败: 如果我像这样完整地注释会话数据类,它确实