Uncatchable ChuckNorrisException

前端 未结 17 2004
时光取名叫无心
时光取名叫无心 2020-12-02 03:34

Is it possible to construct a snippet of code in Java that would make a hypothetical java.lang.ChuckNorrisException uncatchable?

Thoughts that came to m

相关标签:
17条回答
  • 2020-12-02 04:08
    public class ChuckNorrisException extends Exception {
        public ChuckNorrisException() {
            System.exit(1);
        }
    }
    

    (Granted, technically this exception is never actually thrown, but a proper ChuckNorrisException can't be thrown -- it throws you first.)

    0 讨论(0)
  • 2020-12-02 04:09

    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.

    0 讨论(0)
  • 2020-12-02 04:12

    Any exception you throw has to extend Throwable, so it can be always caught. So answer is no.

    If you want to make it difficult to handle, you can override methods getCause(), getMessage(), getStackTrace(), toString() to throw another java.lang.ChuckNorrisException.

    0 讨论(0)
  • 2020-12-02 04:13

    Any code can catch Throwable. So no, whatever exception you create is going to be a subclass of Throwable and will be subject to being caught.

    0 讨论(0)
  • 2020-12-02 04:16

    My answer is based on @jtahlborn's idea, but it's a fully working Java program, that can be packaged into a JAR file and even deployed to your favorite application server as a part of a web application.

    First of all, let's define ChuckNorrisException class so that it doesn't crash JVM from the beginning (Chuck really loves crashing JVMs 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);
        }
    }
    

    Now goes Expendables class to construct it:

    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);
            }
        }
    }
    

    And finally the Main class to kick some butt:

    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");
            }
        }
    }
    

    Compile and run it with following command:

    java -Xverify:none -cp .:<path_to_javassist-3.9.0.GA.jar> chuck.Main
    

    You will get following output:

    before
    finally
    

    No surprise - it's a roundhouse kick after all :)

    0 讨论(0)
提交回复
热议问题