空指针异常 |枚举构造函数中的`this`导致NPE [英] NullPointerException | `this` inside enum constructor causing NPE

查看:20
本文介绍了空指针异常 |枚举构造函数中的`this`导致NPE的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

公共类测试{公共静态无效主(字符串 [] args){Platform1 p1=Platform1.FACEBOOK;//给出空指针异常.Platform2 p2=Platform2.FACEBOOK;//没有NPE 为什么?}}

<小时>

enum Platform1{脸书、优酷、Instagram;平台 1(){初始化(这个);};公共无效初始化(Platform1平台){开关(平台){//平台尚未构建,因此获取`NPE`.//IE.我们在做类似的事情 ->开关(空)导致 NPE.Fine!案例脸书:System.out.println("这是脸书");休息;默认:休息;}}}

<小时>

enum Platform2{FACEBOOK("fb"),YOUTUBE("yt"),INSTAGRAM("ig");私人字符串显示名称;Platform2(字符串显示名称){this.displayName=displayName;初始化(这个);};公共无效初始化(Platform2平台){开关(平台.显示名称){//平台未构建,甚至没有`NPE` &能够访问其属性.//开关(null.displayName)->没有例外 为什么?案例fb":System.out.println("这是脸书");休息;默认:休息;}}}

谁能解释一下为什么在 Platform1 中有 NullPointerException 而在 Platform2 中没有.在第二种情况下,我们如何能够访问枚举对象及其属性,甚至在对象被构造之前?

解决方案

正是如此.正如@PeterS 提到的,在正确构造之前使用枚举会导致 NPE,因为在未构造的枚举上调用了 values() 方法.

还有一点,我想在这里补充一点,Platform1Platform2 都试图在 switch() 中使用未构造的枚举,但 NPE 仅在 中平台1.这背后的原因如下:-

 public void initialize(Platform1 平台){开关(平台){

上面来自 Platform1 枚举的代码在 switch 中使用了 platform 枚举对象,其中内部使用了 $SwitchMap$Platform1[] 数组并且使用 values() 方法来初始化这个数组,从而得到 NPE.但是在 Platform2 中,switch (platform.displayName) 是对已经初始化的 displayName 的比较,因此不会发生字符串比较. >

以下是反编译代码的片段:-

平台 1

 static final int $SwitchMap$Platform1[] =新的 int[Platform1.values().length];

平台 2

switch ((str = platform.displayName).hashCode()){案例3260:如果(str.equals(fb")){

public class Test {
    public static void main(String[] args) {
        Platform1 p1=Platform1.FACEBOOK; //giving NullPointerException.
        Platform2 p2=Platform2.FACEBOOK; //NO NPE why?
    }
}


enum Platform1{
    FACEBOOK,YOUTUBE,INSTAGRAM;
    Platform1(){
        initialize(this);
    };
    public void initialize(Platform1 platform){
        switch (platform) {
        //platform is not constructed yet,so getting `NPE`.
        //ie. we doing something like -> switch (null) causing NPE.Fine!
        case FACEBOOK:
            System.out.println("THIS IS FACEBOOK");
            break;
        default:
            break;
        }
    }
}


enum Platform2{
    FACEBOOK("fb"),YOUTUBE("yt"),INSTAGRAM("ig");
    private String displayName;
    Platform2(String displayName){
        this.displayName=displayName;
        initialize(this);
    };  
    public void initialize(Platform2 platform){
        switch (platform.displayName) {
        //platform not constructed,even No `NPE` & able to access its properties.
        //switch (null.displayName) -> No Exception Why?
        case "fb":
            System.out.println("THIS IS FACEBOOK");
            break;
        default:
            break;
        }
    }
}

Can anyone explain me why there is NullPointerException in Platform1 but not in Platform2. How in the second case we are able to access the enum object and its properties, even before the object is constructed?

解决方案

Exactly. Just as @PeterS mentioned using enum before it has been properly constructed is causing NPE, because values() method is being called on un-constructed enum.

One more point, I would like to add here that Platform1 and Platform2 both are trying to use unconstructed enum in switch() but NPE is only in Platform1. Reason behind this is as follows :-

 public void initialize(Platform1 platform){
        switch (platform) {

Above piece of code from Platform1 enum is using platform enum object in switch where internally $SwitchMap$Platform1[] array is used and to initialize this array values() method is utilized, thus you get NPE. But in Platform2, switch (platform.displayName) is comparison on displayName which is already initialized and a string comparison occurs thus no NPE.

Following are fragments of decompiled code :-

Platform1

 static final int $SwitchMap$Platform1[] =
            new int[Platform1.values().length];

Platform2

switch ((str = platform.displayName).hashCode())
    {
    case 3260: 
      if (str.equals("fb")) {

这篇关于空指针异常 |枚举构造函数中的`this`导致NPE的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆