java static成员变量初始化java.lang.NullPointerException异常

    所谓空指针:就是java中对象的引用为null,string、list、map、类的对象等,初始化或调用其他类得到的结果都可能为null。写java程序时要特别注意空指针对象的引用。这类错误发生的比例很高,一般容易察觉。

    最近碰到一个奇怪的问题,在一个类(类名MyHandler)中有类似初始化:

    private static MyConstruct myconstruct = new MyConstruct();

    MyConstruct是自己写的一个类,里面有一些初始化,异常捕捉,对外提供公用方法。但是该类的初始化依赖配置文件,可能会忘配,所以初始化时可能会抛出空指针异常。

    MyHandler类的调用是通过一个线程去调用,线程中捕捉了Exception。配置文件忘写时,表现的现象就是线程一直在初始化,但从未正常执行。最后检查问题发现是MyConstruct初始化有问题,但是异常信息没有被抛出。

    写了一个测试类,抛出算法异常:

public class testException {
    private static final int k = 1/ 1;

    public static void main(String[] args) {

        try {
            testError error = new testError();
            System.out.println("haha init success");
        }  catch (NullPointerException e) {
            System.out.println("testError throw null point exception");
        }catch (Exception e) {
            System.out.println("get exception");
        }

    }
}

class testError {
    public static int i = 0;
    public static int j = 1 / 0;
    static {
        try {
            j =  1 / 1;
        } catch (Exception e) {
            System.out.println("testError throw exception");
        }
    }

    public void print() {
        System.out.println(j);
    }
}

    运行信息:

Exception in thread "main" java.lang.ExceptionInInitializerError
at testException.main(testException.java:12)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
Caused by: java.lang.ArithmeticException: / by zero
at testError.<clinit>(testException.java:25)
... 6 more


Process finished with exit code 1

    如果static初始化变量时抛出NullPointerException,程序是不能正常捕捉到的,直接运行时退出。

    如果程序改成如下:

扫描二维码关注公众号,回复: 4756203 查看本文章

public class testException {
    private static final int k = 1/ 1;

    public static void main(String[] args) {

        try {
            testError error = new testError();
            System.out.println("haha init success");
        }  catch (NullPointerException e) {
            System.out.println("testError throw null point exception");
        }catch (Exception e) {
            System.out.println("get exception");
        }

    }
}

class testError {
    public static int i = 0;
    public static int j = 1 / 1;
    static {
        try {
            j =  1 / 0;
        } catch (Exception e) {
            System.out.println("testError throw exception");
        }
    }

    public void print() {
        System.out.println(j);
    }
}

        运行信息:

testError throw exception

haha init success

    结论:

        写java程序时要尽量避免NullPointerException,少使用static变量初始化(除非你确定这种初始化不会有异常,不然很难发现祸根),在程序中有可能有异常发生的地方要try catch,这样可以减少排查问题的时间。



    

猜你喜欢

转载自blog.csdn.net/chanllenge/article/details/80493148