在哪种情况下,您应该使用原始类型(int
)还是引用类型(Integer
)?
这question引起了我的好奇心。
答案 0 :(得分:23)
在哪种情况下你应该使用原语 类型(
int
)或引用类型 (Integer
)?
根据经验,我将使用原语(例如int
),除非我必须使用包装原语的类。
其中一个案例是在使用generics的情况下必须使用包装类,如Integer
,因为Java不支持使用基本类型作为类型参数:
List<int> intList = new ArrayList<int>(); // Not allowed.
List<Integer> integerList = new ArrayList<Integer>(); // Allowed.
而且,在很多情况下,我将利用autoboxing and unboxing,因此我不必显式执行从基元到其包装类的转换,反之亦然:
// Autoboxing will turn "1", "2", "3" into Integers from ints.
List<Integer> numbers = Arrays.asList(1, 2, 3);
int sum = 0;
// Integers from the "numbers" List is unboxed into ints.
for (int number : numbers) {
sum += number;
}
另外,作为补充说明,当从基元转换为其包装类对象并且不需要对象的唯一实例时,请使用包装器方法提供的valueOf
方法,因为它执行缓存并返回某个值的相同实例,减少了创建的对象数量:
Integer i1 = Integer.valueOf(1); // Prefer this.
Integer i2 = new Integer(1); // Avoid if not necessary.
有关valueOf
方法的更多信息,Integer.valueOf
方法的API规范可以作为这些方法在基元的包装类中的行为的参考。
答案 1 :(得分:9)
这实际上取决于背景。首先更喜欢原语,因为它更直观,开销更少。如果由于泛型/自动装箱原因不可能,或者您希望它可以为空,那么请选择包装类型(您称之为复杂类型)。
答案 2 :(得分:3)
创建API时我遵循的一般规则可归纳如下:
在#2上,在自动装箱时注意NPE。如果您将方法定义为:
public Integer getValue();
然后按如下方式调用它:
int myValue = getValue();
在getValue()返回null的情况下,你会得到一个没有明显原因的NPE。
答案 3 :(得分:2)
由于Java会执行名为auto-boxing and auto-unboxing的操作,因此在大多数情况下应使用基本类型int
,因为开销较少。
你绝对需要使用Integer的唯一时间是泛型。
List<int> list; // won't compile
List<Integer> list; // correct
答案 4 :(得分:2)
我的经验法则是:只有在需要编译代码时才使用盒装基元。代码中唯一应该出现原始包装类名称的地方是泛型类型参数和静态方法调用:
List<Integer> intList = new ArrayList<Integer>();
int n = Integer.parseInt("123");
这是我给新Java程序员的建议。当他们了解更多时,他们会遇到必须更加挑剔的情况,比如在处理地图或数据库时,但到那时他们也应该更好地理解基元和盒装基元之间的区别。
Autoboxing诱使我们相信int
和Integer
(例如)是可以互换的,但这是一个陷阱。如果您不加选择地混合使用这两种值,则最终可以将两个Integer值与==
进行比较,或者尝试在未实现的情况下取消装箱null
。由此产生的错误可能是间歇性的,很难追查。
比较盒装基元与==
有时的工作方式无关,就好像它正在进行值比较一样。这是一种错觉,这是由于在一定范围内的值在自动装箱过程中自动缓存的事实。这与我们对String值一直存在的问题相同:将它们与==
进行比较有时“有效”,因为您实际上是在比较对同一个缓存对象的两个引用。
在处理字符串时,我们可以告诉n00bs永远不要将它们与==
进行比较,就像我们一直在做的那样。但是将原语与==
进行比较是完全有效的;诀窍(感谢autoboxing)确保这些值确实是原始的。编译器现在让我们将变量声明为Integer
,并将其用作int
;这意味着我们必须行使更高水平的纪律,并在没有充分理由的情况下将其视为错误。
答案 5 :(得分:1)
不要把它们称为“复杂类型”,而是最好将Integer,Double等视为“Classes”,将int,double等视为“原语”。
如果您正在进行任何类型的复杂数学运算,那么基于类的数字表示(如Integer和Double)将会很麻烦并且会减慢您的速度 - 许多数学运算只能使用基元来完成。
另一方面,如果您尝试将数字放入Lists和Maps等集合中,那些集合只能包含对象 - 因此您必须使用(或转换为)类,如Integer和Double。
就个人而言,每当我可以使用原语时,我就会使用原语,只有在输入或输出时才转换为类似Integer的类表示,并且传输需要这些表示。
但是,如果您根本没有进行任何数学计算,而只是直接在代码中传递值,那么您可以通过专门处理基于类的表单(如Integer)来省去一些麻烦。
答案 6 :(得分:0)
我认为没有任何规则。当我编写方法签名,地图,集合,传递的数据对象时,我会选择基本类型(Integer over int)。因此我仍然希望在方法等内部使用Integer而不是int。但是如果你认为这太麻烦了(输入额外的“eger”)那么可以使用int来表示局部变量。
答案 7 :(得分:0)
如果要将setAttribute设置为session,则必须在servlet中使用Integer,Boolean,String等Object。如果要使用值,可以使用基本类型。对象可以为null,但原语不是。如果你想比较基元的类型,使用==但是对象使用.equals,因为在对象比较中==看起来不是值,它看起来是否是相同的对象。使用原语使代码更快。
答案 8 :(得分:0)
可能优先使用Integer
的一种情况是当您使用允许数字条目为空的数据库时,因为您无法用{{1}表示空值}。
但是当然如果你正在进行直接数学运算,那么int
会因为直观性和较少的开销而更好地提及。{/ p>
答案 9 :(得分:0)
我认为这有点晚了但我想加以我的意见以防万一。
在某些情况下,需要使用包装器,因为缺少值与默认值不同。
例如, 对于我工作过的一个项目,屏幕上有一个字段,用户可以在其中输入双倍值,业务要求明确提到如果用户输入0,则意义不同于不输入值并将字段留空并且这差异将在以后的不同模块中产生影响。 所以在这种情况下我们不得不使用Double对象,因为我无法使用原语表示缺少值;因为原语将默认为0,这是该字段的有效输入。
答案 10 :(得分:0)
当我们处理Spring getRequest映射方法时,使用布尔值不起作用。
例如:
@GetMapping("/goal")
public boolean isValidGoal() {
boolean isValid = true;
return isValid;
}
在这种情况下,始终选择布尔值。