2011-12-13 68 views
5

如何评估以下表达式?Java中的自动装箱问题

Student类:

public class Student 
{ 
    private Integer id; 
    // few fields here 

    public Integer getId() 
    { 
     return id; 
    } 

    public void setId(Integer id) 
    { 
     this.id=id; 
    } 

    //setters and getters 
} 

而且在一些方法:

{ 
    int studentId; 

    // few lines here 

    if(studentId==student.getId()) // **1. what about auto-unboxing here? Would it compare correctly? I am not sure.** 
    { 
     //some operation here 
    } 
} 
+2

不要使用包装类,除非你绝对必须。 – mre

+0

是的。你做了什么会工作。我不确定你问了其他什么? – Guillaume

+0

+1不使用包装类:不好的潜在副作用包括不需要的(和隐藏的)NullPointerException抛出您的代码 – Guillaume

回答

4

是的,这将工作就相当于

studentId==student.getId().intValue() 

只要student.id不null

+4

只是出于好奇,拳击和拆箱的规则是什么?我的意思是,为什么Java决定** unbox **'Integer'而不是**框**'int'? – bezmax

+1

是否等于student.id是否为空 –

+0

可能是因为'int'在左边? – red1ynx

1

是的,它会正常工作。但通常不建议使用包装类,直到没有其他人去。

1

比较

studentId==student.getId() 

将工作,但将抛出一个NullPointerException如果studentnull

作为一项规则,自动装箱更喜欢原语,即它会在可能的情况下将Integer转换为int而不是其他方式。你的例子显示了一个很好的理由,因为引用对象的平等是棘手的。因此,它是可能的:

studentId==student.getId().intValue() 

是真实的,但

new Integer(studentId)==student.getId() 

是假的,因为虽然它们具有相同的价值,他们是不是同一个对象。

1

是它会工作,因为这将右操作数转换为对应的数字类型,根据Java语言规范:

如果相等运算符的操作数都是数字型的,或一个是数字另一个可以转换(§5.1.8)为数字类型,则对操作数执行二进制数字提升(第5.6.2节)。

corresponding paragraph in jls

因此,实际上任何一个操作数可以是数字型的for Java来autounbox另一个。

然后§5.1.8说转换包括拆箱转换。corresponing paragraph in jls

1

按照规范,http://docs.oracle.com/javase/1.5.0/docs/guide/language/autoboxing.html

所以,当你应该使用自动装箱和拆箱?仅当引用类型和基元之间存在“阻抗不匹配”时才使用它们,例如,当您必须将数值放入集合中时。对科学计算或其他性能敏感的数字代码使用自动装箱和拆箱并不合适。整数不是int的替代;自动装箱和取消装箱模糊了基本类型和引用类型之间的区别,但它们并没有消除它。

唯一可取的情况下使用包装类(Integer等),当你想在集合中坚持数值,或null是您用例的可接受值。而已。

副作用包括不需要的潜力NullPointerException和性能下降。