是否有可能在Java中构造一段代码,使假设的Java .lang. chucknorrisexception无法捕获?
我想到的是使用拦截器或面向方面的编程。
是否有可能在Java中构造一段代码,使假设的Java .lang. chucknorrisexception无法捕获?
我想到的是使用拦截器或面向方面的编程。
当前回答
我的答案是基于@jtahlborn的想法,但它是一个完全可用的Java程序,可以打包到JAR文件中,甚至可以作为web应用程序的一部分部署到您最喜欢的应用服务器上。
首先,让我们定义ChuckNorrisException类,这样它就不会从一开始就崩溃JVM(顺便说一句,Chuck真的很喜欢崩溃JVM:)
package chuck;
import java.io.PrintStream;
import java.io.PrintWriter;
public class ChuckNorrisException extends Exception {
public ChuckNorrisException() {
}
@Override
public Throwable getCause() {
return null;
}
@Override
public String getMessage() {
return toString();
}
@Override
public void printStackTrace(PrintWriter s) {
super.printStackTrace(s);
}
@Override
public void printStackTrace(PrintStream s) {
super.printStackTrace(s);
}
}
现在让敢死队来构建它:
package chuck;
import javassist.*;
public class Expendables {
private static Class clz;
public static ChuckNorrisException getChuck() {
try {
if (clz == null) {
ClassPool pool = ClassPool.getDefault();
CtClass cc = pool.get("chuck.ChuckNorrisException");
cc.setSuperclass(pool.get("java.lang.Object"));
clz = cc.toClass();
}
return (ChuckNorrisException)clz.newInstance();
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
}
最后是Main类:
package chuck;
public class Main {
public void roundhouseKick() throws Exception {
throw Expendables.getChuck();
}
public void foo() {
try {
roundhouseKick();
} catch (Throwable ex) {
System.out.println("Caught " + ex.toString());
}
}
public static void main(String[] args) {
try {
System.out.println("before");
new Main().foo();
System.out.println("after");
} finally {
System.out.println("finally");
}
}
}
使用以下命令编译并运行它:
java -Xverify:none -cp .:<path_to_javassist-3.9.0.GA.jar> chuck.Main
您将得到以下输出:
before
finally
这并不奇怪,毕竟这是一个回旋踢:)
其他回答
我的答案是基于@jtahlborn的想法,但它是一个完全可用的Java程序,可以打包到JAR文件中,甚至可以作为web应用程序的一部分部署到您最喜欢的应用服务器上。
首先,让我们定义ChuckNorrisException类,这样它就不会从一开始就崩溃JVM(顺便说一句,Chuck真的很喜欢崩溃JVM:)
package chuck;
import java.io.PrintStream;
import java.io.PrintWriter;
public class ChuckNorrisException extends Exception {
public ChuckNorrisException() {
}
@Override
public Throwable getCause() {
return null;
}
@Override
public String getMessage() {
return toString();
}
@Override
public void printStackTrace(PrintWriter s) {
super.printStackTrace(s);
}
@Override
public void printStackTrace(PrintStream s) {
super.printStackTrace(s);
}
}
现在让敢死队来构建它:
package chuck;
import javassist.*;
public class Expendables {
private static Class clz;
public static ChuckNorrisException getChuck() {
try {
if (clz == null) {
ClassPool pool = ClassPool.getDefault();
CtClass cc = pool.get("chuck.ChuckNorrisException");
cc.setSuperclass(pool.get("java.lang.Object"));
clz = cc.toClass();
}
return (ChuckNorrisException)clz.newInstance();
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
}
最后是Main类:
package chuck;
public class Main {
public void roundhouseKick() throws Exception {
throw Expendables.getChuck();
}
public void foo() {
try {
roundhouseKick();
} catch (Throwable ex) {
System.out.println("Caught " + ex.toString());
}
}
public static void main(String[] args) {
try {
System.out.println("before");
new Main().foo();
System.out.println("after");
} finally {
System.out.println("finally");
}
}
}
使用以下命令编译并运行它:
java -Xverify:none -cp .:<path_to_javassist-3.9.0.GA.jar> chuck.Main
您将得到以下输出:
before
finally
这并不奇怪,毕竟这是一个回旋踢:)
在构造函数中,可以启动一个反复调用originalThread的线程。停止(ChuckNorisException.this)
线程可以重复捕获异常,但会一直抛出异常,直到异常死亡。
抛出的任何异常都必须扩展Throwable,因此总是可以捕获它。所以答案是否定的。
如果你想让它难以处理,你可以重写方法getCause(), getMessage(), getStackTrace(), toString()抛出另一个java.lang.ChuckNorrisException。
Java中唯一的chucknorrisexception应该是OutOfMemoryError和StackOverflowError。
实际上,您可以“捕获”它们,这意味着在抛出异常时将执行catch(OutOfMemoryError ex),但该块将自动将异常重新抛出给调用者。
我不认为公共类ChuckNorrisError extends Error可以解决这个问题,但是你可以尝试一下。我没有找到关于扩展错误的文档
不。Java中的所有异常都必须成为Java .lang的子类。虽然这可能不是一个好的实践,但你可以像这样捕获每种类型的异常:
try {
//Stuff
} catch ( Throwable T ){
//Doesn't matter what it was, I caught it.
}
有关更多信息,请参阅java.lang.Throwable文档。
如果您试图避免检查异常(必须显式处理的异常),那么您将希望继承Error或RuntimeException类。