잡을 수없는 ChuckNorrisException
가설을 잡을 수 없게 만드는 코드 조각을 Java 로 구성 할 수 java.lang.ChuckNorrisException
있습니까?
떠오른 생각은 예를 들어 인터셉터 또는 측면 지향 프로그래밍을 사용하고 있습니다.
경우 나도 몰라 그래서 나는이 시도하지 않은 JVM은 이 같은 제한,하지만 어쩌면 당신은 발생 코드를 컴파일 할 수 ChuckNorrisException
있지만, 실행시의 클래스 정의를 제공 ChuckNorrisException
하는 Throwable를 확장하지 않습니다 .
최신 정보:
작동하지 않습니다. 검증 자 오류를 생성합니다.
Exception in thread "main" java.lang.VerifyError: (class: TestThrow, method: ma\
in signature: ([Ljava/lang/String;)V) Can only throw Throwable objects
Could not find the main class: TestThrow. Program will exit.
업데이트 2 :
사실, 바이트 코드 검증기를 비활성화하면이 작업을 수행 할 수 있습니다! ( -Xverify:none
)
업데이트 3 :
집에서 팔로우하는 사람들을 위해 다음은 전체 스크립트입니다.
다음 클래스를 만듭니다.
public class ChuckNorrisException
extends RuntimeException // <- Comment out this line on second compilation
{
public ChuckNorrisException() { }
}
public class TestVillain {
public static void main(String[] args) {
try {
throw new ChuckNorrisException();
}
catch(Throwable t) {
System.out.println("Gotcha!");
}
finally {
System.out.println("The end.");
}
}
}
클래스 컴파일 :
javac -cp . TestVillain.java ChuckNorrisException.java
운영:
java -cp . TestVillain
Gotcha!
The end.
"extends RuntimeException"을 주석 처리하고 다음 만 다시 컴파일하십시오ChuckNorrisException.java
.
javac -cp . ChuckNorrisException.java
운영:
java -cp . TestVillain
Exception in thread "main" java.lang.VerifyError: (class: TestVillain, method: main signature: ([Ljava/lang/String;)V) Can only throw Throwable objects
Could not find the main class: TestVillain. Program will exit.
확인없이 실행 :
java -Xverify:none -cp . TestVillain
The end.
Exception in thread "main"
이것을 숙고 한 후에 나는 잡을 수없는 예외를 성공적으로 만들었다. JulesWinnfield
그러나 나는 버섯 구름을 낳는 어머니의 예외이기 때문에 Chuck이 아니라 이름을 지정했습니다 . 더욱이 그것은 당신이 생각했던 것과 정확히 일치하지 않을 수도 있지만 확실히 잡힐 수는 없습니다. 관찰 :
public static class JulesWinnfield extends Exception
{
JulesWinnfield()
{
System.err.println("Say 'What' again! I dare you! I double dare you!");
System.exit(25-17); // And you shall know I am the LORD
}
}
public static void main(String[] args)
{
try
{
throw new JulesWinnfield();
}
catch(JulesWinnfield jw)
{
System.out.println("There's a word for that Jules - a bum");
}
}
Et voila! 포착되지 않은 예외입니다.
산출:
운영:
다시 '무엇'이라고 말하세요! 감히! 나는 당신을 두 배로 감히!
자바 결과 : 8
BUILD SUCCESSFUL (총 시간 : 0 초)
시간이 조금 더 있으면 다른 것도 생각할 수 없는지 살펴 보겠습니다.
또한 다음을 확인하십시오.
public static class JulesWinnfield extends Exception
{
JulesWinnfield() throws JulesWinnfield, VincentVega
{
throw new VincentVega();
}
}
public static class VincentVega extends Exception
{
VincentVega() throws JulesWinnfield, VincentVega
{
throw new JulesWinnfield();
}
}
public static void main(String[] args) throws VincentVega
{
try
{
throw new JulesWinnfield();
}
catch(JulesWinnfield jw)
{
}
catch(VincentVega vv)
{
}
}
스택 오버플로가 발생합니다. 다시 예외가 잡히지 않은 상태로 유지됩니다.
이러한 예외 System.exit(Integer.MIN_VALUE);
가있는 경우 생성자에서 를 사용하는 것은 분명히 필수입니다. 왜냐하면 그러한 예외를 던지면 발생하는 일이기 때문입니다.)
모든 코드는 Throwable을 잡을 수 있습니다. 따라서 어떤 예외를 생성하든 Throwable의 하위 클래스가되어 포착 될 수 있습니다.
public class ChuckNorrisException extends Exception {
public ChuckNorrisException() {
System.exit(1);
}
}
( 기술적 으로이 예외는 실제로 발생하지 않지만 적절한 예외는 ChuckNorrisException
발생할 수 없습니다. 먼저 발생합니다.)
던지는 모든 예외는 Throwable을 확장해야하므로 항상 잡을 수 있습니다. 그래서 대답은 아니오입니다.
당신이 그것을 어렵게 처리 할 수 있도록하려는 경우, 당신은 방법을 대체 할 수 있습니다 getCause(), getMessage()
, getStackTrace()
, toString()
서로를 던져 java.lang.ChuckNorrisException
.
내 대답은 @jtahlborn의 아이디어를 기반으로하지만 완전히 작동하는 Java 프로그램으로, JAR 파일 로 패키징 할 수 있으며 웹 애플리케이션 의 일부로 좋아하는 애플리케이션 서버에 배포 할 수도 있습니다 .
우선 ChuckNorrisException
, 처음부터 JVM이 충돌하지 않도록 클래스를 정의합시다 (Chuck은 JVM 충돌을 정말 좋아합니다. BTW :)
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);
}
}
이제 Expendables
그것을 구성하기 위해 수업이 진행 됩니다.
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.stop (ChuckNorisException.this)
스레드는 예외를 반복적으로 포착 할 수 있지만 죽을 때까지 계속 발생시킵니다.
No. All exceptions in Java must subclass java.lang.Throwable
, and although it may not be good practice, you can catch every type of exception like so:
try {
//Stuff
} catch ( Throwable T ){
//Doesn't matter what it was, I caught it.
}
See the java.lang.Throwable documentation for more information.
If you're trying to avoid checked exceptions (ones that must be explicitly handled) then you will want to subclass Error, or RuntimeException.
Actually the accepted answer is not so nice because Java needs to be run without verification, i.e. the code would not work under normal circumstances.
AspectJ to the rescue for the real solution!
Exception class:
package de.scrum_master.app;
public class ChuckNorrisException extends RuntimeException {
public ChuckNorrisException(String message) {
super(message);
}
}
Aspect:
package de.scrum_master.aspect;
import de.scrum_master.app.ChuckNorrisException;
public aspect ChuckNorrisAspect {
before(ChuckNorrisException chuck) : handler(*) && args(chuck) {
System.out.println("Somebody is trying to catch Chuck Norris - LOL!");
throw chuck;
}
}
Sample application:
package de.scrum_master.app;
public class Application {
public static void main(String[] args) {
catchAllMethod();
}
private static void catchAllMethod() {
try {
exceptionThrowingMethod();
}
catch (Throwable t) {
System.out.println("Gotcha, " + t.getClass().getSimpleName() + "!");
}
}
private static void exceptionThrowingMethod() {
throw new ChuckNorrisException("Catch me if you can!");
}
}
Output:
Somebody is trying to catch Chuck Norris - LOL!
Exception in thread "main" de.scrum_master.app.ChuckNorrisException: Catch me if you can!
at de.scrum_master.app.Application.exceptionThrowingMethod(Application.java:18)
at de.scrum_master.app.Application.catchAllMethod(Application.java:10)
at de.scrum_master.app.Application.main(Application.java:5)
A variant on the theme is the surprising fact that you can throw undeclared checked exceptions from Java code. Since it is not declared in the methods signature, the compiler won't let you catch the exception itself, though you can catch it as java.lang.Exception.
Here's a helper class that lets you throw anything, declared or not:
public class SneakyThrow {
public static RuntimeException sneak(Throwable t) {
throw SneakyThrow.<RuntimeException> throwGivenThrowable(t);
}
private static <T extends Throwable> RuntimeException throwGivenThrowable(Throwable t) throws T {
throw (T) t;
}
}
Now throw SneakyThrow.sneak(new ChuckNorrisException());
does throw a ChuckNorrisException, but the compiler complains in
try {
throw SneakyThrow.sneak(new ChuckNorrisException());
} catch (ChuckNorrisException e) {
}
about catching an exception that is not thrown if ChuckNorrisException is a checked exception.
The only ChuckNorrisException
s in Java should be OutOfMemoryError
and StackOverflowError
.
You can actually "catch" them in the means that a catch(OutOfMemoryError ex)
will execute in case the exception is thrown, but that block will automatically rethrow the exception to the caller.
I don't think that public class ChuckNorrisError extends Error
does the trick but you could give it a try. I found no documentation about extending Error
Is it possible to construct a snippet of code in java that would make a hypothetical java.lang.ChuckNorrisException uncatchable?
Yes, and here's the answer: Design your java.lang.ChuckNorrisException
such that it is not an instance of java.lang.Throwable
. Why? An unthrowable object is uncatchable by definition because you can never catch something that can never be thrown.
You can keep ChuckNorris internal or private and encapsulate him or swollow him...
try { doChuckAction(); } catch(ChuckNorrisException cne) { /*do something else*/ }
Two fundamental problems with exception handling in Java are that it uses the type of an exception to indicate whether action should be taken based upon it, and that anything which takes action based upon an exception (i.e. "catch"es it) is presumed to resolve the underlying condition. It would be useful to have a means by which an exception object could decide which handlers should execute, and whether the handlers that have executed so far have cleaned things up enough for the present method to satisfy its exit conditions. While this could be used to make "uncatchable" exceptions, two bigger uses would be to (1) make exceptions which will only be considered handled when they're caught by code that actually knows how to deal with them, and (2) allow for sensible handling of exceptions which occur in a finally
block (if a FooException
during a finally
block during the unwinding of a BarException
, both exceptions should propagate up the call stack; both should be catchable, but unwinding should continue until both have been caught). Unfortunately, I don't think there would be any way to make existing exception-handling code work that way without breaking things.
It is easily possible to simulate a uncaught exception on the current thread. This will trigger the regular behavior of an uncaught exception, and thus gets the job done semantically. It will, however, not necessarily stop the current thread's execution, as no exception is actually thrown.
Throwable exception = /* ... */;
Thread currentThread = Thread.currentThread();
Thread.UncaughtExceptionHandler uncaughtExceptionHandler =
currentThread.getUncaughtExceptionHandler();
uncaughtExceptionHandler.uncaughtException(currentThread, exception);
// May be reachable, depending on the uncaught exception handler.
This is actually useful in (very rare) situations, for example when proper Error
handling is required, but the method is invoked from a framework catching (and discarding) any Throwable
.
Call System.exit(1) in the finalize
, and just throw a copy of the exception from all the other methods, so that the program will exit.
참고URL : https://stackoverflow.com/questions/13883166/uncatchable-chucknorrisexception
'programing tip' 카테고리의 다른 글
경로의 일부를 찾을 수 없습니다.… bin \ roslyn \ csc.exe (0) | 2020.10.03 |
---|---|
Python 스크립트를 독립 실행 형으로 실행하여 종속성없이 실행하는 방법은 무엇입니까? (0) | 2020.10.03 |
REST 이해 : 동사, 오류 코드 및 인증 (0) | 2020.10.03 |
여러 클래스 제거 (jQuery) (0) | 2020.10.03 |
Jackson with JSON : Unrecognized field, not mark as ignorable (0) | 2020.10.03 |