Java:构造函数中的NULL

Lis*_*nne 8 java constructor nullpointerexception

请问这个问题有点理论,但我想理解.

为什么我将null参数传递给构造函数NullPointerException?

这是我的榜样

new AttendeeDetail("Gus Goose","1151","15-01-2012",(Integer) null,null) 
Run Code Online (Sandbox Code Playgroud)

这是班级:

public class AttendeeDetail {

    private String ticketholder_name;
    private String user_id;
    private String date_of_birth;
    private int tickets_purchased;
    private ArrayList<Ticket> tickets;

    public AttendeeDetail(String ticketholder_name, String user_id, 
        String date_of_birth, int tickets_purchased, ArrayList<Ticket> tickets) 
    {
        this.ticketholder_name=ticketholder_name;
        this.user_id=user_id;
        this.date_of_birth=date_of_birth;
        this.tickets_purchased=tickets_purchased;
        this.tickets=tickets;
    }
}
Run Code Online (Sandbox Code Playgroud)

jha*_*mon 7

一个int不可能null.如果确实需要传递空值,请使用该Integer类型


wes*_*ton 6

你分配一个Integer:(Integer) null一个int参数:int tickets_purchased.

Integer,作为引用类型可以null,但int作为基本类型不能,因此在尝试转换期间发生错误.

此转换称为拆箱操作.


izs*_*tas 6

请考虑以下代码:

public class Main {
    public static void main(String[] args) {
        Integer wrapped = null;
        int primitive = wrapped;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,让我们看看这段代码使用javap以下内容编译:

public static void main(java.lang.String[]);
Code:
   0: aconst_null
   1: astore_1
   2: aload_1
   3: invokevirtual #2                  // Method java/lang/Integer.intValue:()I
   6: istore_2
   7: return
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,为了取消装箱,Integer它尝试Integer#intValue()在null引用时调用方法,因此它会抛出NullPointerException.


Ste*_*n C 5

正如其他答案所提到的,问题是这个 - (Integer) null.

当方法参数的正式类型是int并且您尝试传递时(Integer) null,将发生以下情况.

  1. Java编译器会说"啊!我有一个Integer值,我需要将它转换为一个int值.我会输出代码来取消它!" .

  2. Integer.intValue()取消装箱值的代码是使用要取消装箱的值作为目标对象的调用.除了值是null......不是真正的对象引用.

  3. 在运行时,你最终调用intValue()的null,而且抛出NPE.

一些编译器会发出警告,说代码总是会抛出一个NPE.但是,这是合法的Java代码,因此符合标准的Java编译器不能将其称为编译错误.


可能的解决方案:

  1. 不要(Integer) null用作参数.传递int值或实际(非空)Integer对象.在这种情况下,零看起来像一个合理的替代品.

  2. 将形式参数的类型更改int为Integer...并将更改传播到返回,使用等对应字段值的位置.

第一种选择可能是正确的,除非你真的需要模拟"参与者"购买了未知数量的门票的可能性.(如果你确实需要对其进行建模,那么你的应用程序必须以某种方式应对这种可能性.)