Java:如何在Singleton中重现Legen ... Dary ClassNotFoundException?

les*_*hka 5 java singleton exception classnotfoundexception

在我上次的采访中,我被问到一个关于java中所有Singleton实现的标准问题.他们都有多糟糕.

我被告知,即使静态初始化也很糟糕,因为构造函数中出现未经检查的异常的可能性:

public class Singleton {
    private static Singleton instance = new Singleton();

    public static Singleton getInstance() {
        return instance;
    }
    private Singleton() {
       throw new RuntimeException("Wow... Exception in Singleton constructor...");
    }
}
Run Code Online (Sandbox Code Playgroud)

他们还告诉我,Exception将是"ClassNotFoundException",因此在真正的应用程序中找到问题非常困难.

我试图得到那个例外:

public static void main(String[] args) {
    new Thread(new Runnable(){
            public void run() {
                Singleton.getInstance();
            }
        }).start();
}
Run Code Online (Sandbox Code Playgroud)

但我唯一得到的是ExceptionInInitializerError ......

我搜索了这个例外以及我发现的所有地方 - 他们都谈到了我在采访中被告知的同样问题.没有关于"实施"=)

感谢您的关注.

Pet*_*rey 5

有时你在面试中会遇到奇怪的问题,你应该总是期待意外.;)

你使用的任何技术都有正面和缺点.您必须知道何时是使用它们的好时机,问题可能是什么以及如何解决它们.

重要的是要记住,几乎每个问题都有解决方案或解决方法.

在我上次的采访中,我被问到一个关于java中所有Singleton实现的标准问题.他们都有多糟糕.

听起来不像是一个问题,更像是一场宗教辩论.

我被告知,即使静态初始化也很糟糕,因为构造函数中出现未经检查的异常的可能性:

Siderman IV:蜘蛛侠vs Singleton和静态初始化者.(坏人;)

抛出新的RuntimeException("哇......在Singleton构造函数中的异常......");

这是一个坏主意,所以不要这样做.实际上它甚至都不会编译.Java 6中的编译器报告.

initializer must be able to complete normally
Run Code Online (Sandbox Code Playgroud)

他们还告诉我,Exception将是"ClassNotFoundException",因此在真正的应用程序中找到问题非常困难.

您得到一个ExceptionInInitializerError,其中包含导致该问题的异常原因.除了必须阅读嵌套异常之外,它并不是那么棘手.

static class Inner {
    static {
        Integer.parseInt(null);
    }
}

public static void main(String... args) {
    try {
        new Inner();
    } catch (Throwable e) {
        e.printStackTrace();
    }
    new Inner();
}
Run Code Online (Sandbox Code Playgroud)

版画

Exception in thread "main" java.lang.ExceptionInInitializerError
at Main.main(Main.java:12)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: java.lang.NumberFormatException: null
at java.lang.Integer.parseInt(Integer.java:417)
at java.lang.Integer.parseInt(Integer.java:499)
at Main$Inner.<clinit>(Main.java:8)

Exception in thread "main" java.lang.NoClassDefFoundError: Could not initialize class Main$Inner
at Main.main(Main.java:14)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Run Code Online (Sandbox Code Playgroud)

这是第一次发生,之后如果您再次尝试使用该类,则会得到NoClassDefFoundError.

过去,当您尝试使用反射访问类时,它失败了,您得到了一个ClassNotFoundException(没有关于实际发生的事情的详细信息)但是现在不再是这种情况了.