何时使用原语和Java中的引用类型

时间:2022-06-08 13:15:03

In which case should you use primitive types(int) or reference types (Integer)?

在哪种情况下,您应该使用原始类型(int)或引用类型(整数)?

This question sparked my curiosity.

这个问题引起了我的好奇心。

10 个解决方案

#1


22  

In which case should you use primitive types(int) or reference types (Integer)?

在哪种情况下,您应该使用原始类型(int)或引用类型(整数)?

As a rule of thumb, I will use a primitive (such as int) unless I have to use a class that wraps a primitive.

根据经验,我将使用原语(如int),除非我必须使用包装原语的类。

One of the cases were one must use a wrapper class such as Integer is in the case of using generics, as Java does not support the use of primitive types as type parameters:

其中一个案例是必须使用包装类,例如Integer,在使用泛型的情况下,因为Java不支持使用原始类型作为类型参数:

List<int> intList = new ArrayList<int>();               // Not allowed.
List<Integer> integerList = new ArrayList<Integer>();   // Allowed.

And, in many cases, I will take advantage of autoboxing and unboxing, so I don't have to explicitly perform conversions from primitives to its wrapper class and vice versa:

并且,在许多情况下,我将利用自动装箱和拆箱,因此我不必显式执行从基元到其包装类的转换,反之亦然:

// 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;
}

Also, as an additional note, when converting from primitives to its wrapper class objects, and unique instances of objects are not necessary, use the valueOf method provided by the wrapper method, as it performs caching and return the same instance for a certain value, reducing the number of objects which are created:

另外,作为补充说明,当从基元转换为其包装类对象时,并且不需要对象的唯一实例时,请使用包装器方法提供的valueOf方法,因为它执行缓存并为特定值返回相同的实例,减少创建的对象数量:

Integer i1 = Integer.valueOf(1);   // Prefer this.
Integer i2 = new Integer(1);       // Avoid if not necessary.

For more information on the valueOf methods, the API specification for the Integer.valueOf method can serve as a reference for how those methods will behave in the wrapper classes for primitives.

有关valueOf方法的更多信息,Integer.valueOf方法的API规范可以作为这些方法在基元的包装类中的行为的参考。

#2


9  

That really depends on the context. First prefer the primitive, because it's more intuitive and has less overhead. If it is not possible for generics/autoboxing reasons, or if you want it to be nullable, then go for the wrapper type (complex type as you call it).

这实际上取决于背景。首先更喜欢原语,因为它更直观,开销更少。如果由于泛型/自动装箱原因不可能,或者您希望它可以为空,那么请选择包装类型(您称之为复杂类型)。

#3


3  

My rule of thumb is: use boxed primitives only when it's necessary to get the code to compile. The only places in your code where the names of the primitive wrapper classes should appear is in generic type parameters and static method calls:

我的经验法则是:只有在需要编译代码时才使用盒装基元。代码中唯一应该出现原始包装类名称的地方是泛型类型参数和静态方法调用:

List<Integer> intList = new ArrayList<Integer>();

int n = Integer.parseInt("123");

That's the advice I would give to new Java programmers. As they learn more, they'll run into situations where they have to be more discerning, like when dealing with Maps or databases, but by then they should also have a better understanding of the difference between primitives and boxed primitives.

这是我给新Java程序员的建议。随着他们学到更多,他们将遇到他们必须更加挑剔的情况,比如在处理地图或数据库时,但到那时他们也应该更好地理解基元和盒装基元之间的差异。

Autoboxing tempts us to believe int and Integer (for example) are interchangeable, but it's a trap. If you mix the two kinds of value indiscriminately, you can end up comparing two Integer values with == or trying to unbox a null without realizing it. The resulting bugs can be intermittent and difficult to track down.

Autoboxing诱使我们相信int和Integer(例如)是可以互换的,但它是一个陷阱。如果你不加选择地混合使用这两种值,你最终可以将两个Integer值与==进行比较,或者试图在没有意识到的情况下取消空值。由此产生的错误可能是间歇性的,很难追查。

It doesn't help that comparing boxed primitives with == sometimes works as if it were doing a value comparison. It's an illusion caused by the fact that values within a certain range are automatically cached in the process of autoboxing. It's the same problem we've always had with String values: comparing them with == sometimes "works" because you're actually comparing two references to the same, cached object.

将盒装基元与==进行比较有时无助于进行值比较。这是一种错觉,这是由于某个范围内的值在自动装箱过程中自动缓存的事实造成的。这与我们对String值一直存在的问题相同:将它们与==进行比较有时“工作”,因为您实际上是在比较对同一个缓存对象的两个引用。

When dealing with strings we can just tell the n00bs never to compare them with ==, as we've been doing all along. But comparing primitives with == is perfectly valid; the trick (thanks to autoboxing) is being sure the values really are primitives. The compiler will now let us declare a variable as an Integer and use it as if it were an int; that means we have to exercise a greater level of discipline and treat it as an error when someone does so without good reason.

在处理字符串时,我们可以告诉n00bs永远不要将它们与==进行比较,就像我们一直在做的那样。但是将原语与==进行比较是完全有效的;诀窍(感谢autoboxing)确保这些值确实是原始的。编译器现在让我们将一个变量声明为一个Integer并使用它就好像它是一个int;这意味着我们必须行使更高水平的纪律,并在没有充分理由的情况下将其视为错误。

#4


2  

Since Java does something called auto-boxing and auto-unboxing, you should use the primitive type int in most cases because of less overhead.

由于Java执行自动装箱和自动拆箱的操作,因此在大多数情况下应使用基本类型int,因为开销较少。

The only time you absolutely need to use Integer is in generics.

你绝对需要使用Integer的唯一时间是泛型。

List<int> list; // won't compile
List<Integer> list; // correct

#5


2  

The general rules I follow when creating an API can be summarized as follows:

我在创建API时遵循的一般规则可归纳如下:

  1. If the method must return an value, use a primitive type
  2. 如果方法必须返回值,请使用基本类型
  3. If the method may not always apply (eg: getRadioId(...) on an object where such an ID may not exist), then return an Integer and specify in the JavaDocs that the method will return null in some cases.
  4. 如果该方法可能并不总是适用(例如:getRadioId(...)在可能不存在此类ID的对象上),则返回一个Integer并在JavaDocs中指定该方法在某些情况下将返回null。

On #2, look out for NPEs when autoboxing. If you have a method defined as:

在#2上,在自动装箱时注意NPE。如果您将方法定义为:

public Integer getValue();

And then call it as follows:

然后按如下方式调用它:

int myValue = getValue();

In the case where getValue() returns null you'll get an NPE without an obvious cause.

在getValue()返回null的情况下,您将获得没有明显原因的NPE。

#6


1  

Rather than calling them "complex types", you'd be best served thinking Integer, Double, etc. as "Classes", and int, double, etc. as "primitives".

而不是称它们为“复杂类型”,你最好将Integer,Double等视为“Classes”,将int,double等视为“原语”。

If you're doing any type of sophisticated math, the Class-based numeric representation like Integer and Double will be cumbersome and slow you down - many math operations can only be done with primitives.

如果您正在进行任何类型的复杂数学运算,那么基于类的数​​字表示(如Integer和Double)将会很麻烦并且会让您失望 - 许多数学运算只能使用基元来完成。

On the other hand, if you're trying to put your numbers into collections like Lists and Maps, those collections can only contain objects - and thus you must use (or convert to) classes like Integer and Double.

另一方面,如果您尝试将数字放入Lists和Maps等集合中,那些集合只能包含对象 - 因此您必须使用(或转换为)类,如Integer和Double。

Personally, I use primitives whenever I can get away with it, and only convert to the Class representations like Integer when it's time to do input or output, and the transport requires those representations.

就个人而言,每当我可以使用它时,我就会使用原语,并且只有在输入或输出时才转换为类似Integer的类表示,并且传输需要这些表示。

However, if you aren't doing any math at all, and instead are just passing the values straight through your code, you might save yourself some trouble by dealing with the Class-based forms (like Integer) exclusively.

但是,如果您根本不进行任何数学运算,而只是直接在代码中传递值,则可以通过专门处理基于类的表单(如Integer)来省去一些麻烦。

#7


0  

I dont think there is any rule as such. I would choose the types over primitives (Integer over int) when I write method signatures, Maps, collections, Data Objects that get passed around. As such I would still like to use Integer instead of int even inside of methods etc. But if you think that is too much trouble (to type extra "eger") then it is okay to use ints for local variables.

我不认为有这样的规则。当我编写方法签名,地图,集合,传递的数据对象时,我会选择基本类型(Integer over int)。因此我仍然希望在方法等内部使用Integer而不是int。但是如果你认为这太麻烦了(输入额外的“eger”)那么可以使用int来表示局部变量。

#8


0  

If you want to setAttribute to session you have to use Object like Integer,Boolean,String in servlets. If you want to use value you can use primitive types. Objects may be null but primitives not. And if you want to compare types for primitives use == but objects use .equals because in object comparision == looks not values it looks if these are the same objects. And using primitives makes faster the code.

如果要将setAttribute设置为session,则必须在servlet中使用Integer,Boolean,String等Object。如果要使用值,可以使用基本类型。对象可以为null,但原语不是。如果你想比较基元的类型,使用==但是对象使用.equals,因为在对象比较中==看起来不是值,它看起来是否是相同的对象。使用原语使代码更快。

#9


0  

One case in which Integer might be prefered is when you are working with a database where numerical entries are allowed to be null, since you wouldn't be able to represent a null value with an int.

可能更喜欢Integer的一种情况是,当您使用数据库时允许数字条目为空时,因为您无法用int表示空值。

But of course if you're doing straight math, then int would be better as others have mentioned due to intuitiveness and less overhead.

但是当然如果你正在进行直接数学运算,那么由于直观性和较少的开销,int会更好。

#10


0  

I think this is a bit late but I wanted to add my opinion just in case.

我认为这有点晚了但我想加以我的意见以防万一。

in some scenarios, it's required to use the wrappers as the lack of a value is different from the default value.

在某些情况下,需要使用包装器,因为缺少值与默认值不同。

example, for one project I worked on, there was a field on screen where the user could enter a double value, the business requirement clearly mentioned that if the user enters a 0 the meaning is different from not entering a value and leaving the field blank and this difference will make an impact later on in a different module. so in this scenario we had to use the Double object, since I cannot represent a lack of value using the primitive; since the primitive will default to 0 which was a valid input for the field.

例如,对于我工作的一个项目,屏幕上有一个字段,用户可以在其中输入双倍值,业务要求明确提到如果用户输入0,则意义不同于不输入值并将该字段留空而这种差异将在以后的不同模块中产生影响。所以在这种情况下我们不得不使用Double对象,因为我无法使用原语来表示缺少值;因为原语将默认为0,这是该字段的有效输入。

#1


22  

In which case should you use primitive types(int) or reference types (Integer)?

在哪种情况下,您应该使用原始类型(int)或引用类型(整数)?

As a rule of thumb, I will use a primitive (such as int) unless I have to use a class that wraps a primitive.

根据经验,我将使用原语(如int),除非我必须使用包装原语的类。

One of the cases were one must use a wrapper class such as Integer is in the case of using generics, as Java does not support the use of primitive types as type parameters:

其中一个案例是必须使用包装类,例如Integer,在使用泛型的情况下,因为Java不支持使用原始类型作为类型参数:

List<int> intList = new ArrayList<int>();               // Not allowed.
List<Integer> integerList = new ArrayList<Integer>();   // Allowed.

And, in many cases, I will take advantage of autoboxing and unboxing, so I don't have to explicitly perform conversions from primitives to its wrapper class and vice versa:

并且,在许多情况下,我将利用自动装箱和拆箱,因此我不必显式执行从基元到其包装类的转换,反之亦然:

// 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;
}

Also, as an additional note, when converting from primitives to its wrapper class objects, and unique instances of objects are not necessary, use the valueOf method provided by the wrapper method, as it performs caching and return the same instance for a certain value, reducing the number of objects which are created:

另外,作为补充说明,当从基元转换为其包装类对象时,并且不需要对象的唯一实例时,请使用包装器方法提供的valueOf方法,因为它执行缓存并为特定值返回相同的实例,减少创建的对象数量:

Integer i1 = Integer.valueOf(1);   // Prefer this.
Integer i2 = new Integer(1);       // Avoid if not necessary.

For more information on the valueOf methods, the API specification for the Integer.valueOf method can serve as a reference for how those methods will behave in the wrapper classes for primitives.

有关valueOf方法的更多信息,Integer.valueOf方法的API规范可以作为这些方法在基元的包装类中的行为的参考。

#2


9  

That really depends on the context. First prefer the primitive, because it's more intuitive and has less overhead. If it is not possible for generics/autoboxing reasons, or if you want it to be nullable, then go for the wrapper type (complex type as you call it).

这实际上取决于背景。首先更喜欢原语,因为它更直观,开销更少。如果由于泛型/自动装箱原因不可能,或者您希望它可以为空,那么请选择包装类型(您称之为复杂类型)。

#3


3  

My rule of thumb is: use boxed primitives only when it's necessary to get the code to compile. The only places in your code where the names of the primitive wrapper classes should appear is in generic type parameters and static method calls:

我的经验法则是:只有在需要编译代码时才使用盒装基元。代码中唯一应该出现原始包装类名称的地方是泛型类型参数和静态方法调用:

List<Integer> intList = new ArrayList<Integer>();

int n = Integer.parseInt("123");

That's the advice I would give to new Java programmers. As they learn more, they'll run into situations where they have to be more discerning, like when dealing with Maps or databases, but by then they should also have a better understanding of the difference between primitives and boxed primitives.

这是我给新Java程序员的建议。随着他们学到更多,他们将遇到他们必须更加挑剔的情况,比如在处理地图或数据库时,但到那时他们也应该更好地理解基元和盒装基元之间的差异。

Autoboxing tempts us to believe int and Integer (for example) are interchangeable, but it's a trap. If you mix the two kinds of value indiscriminately, you can end up comparing two Integer values with == or trying to unbox a null without realizing it. The resulting bugs can be intermittent and difficult to track down.

Autoboxing诱使我们相信int和Integer(例如)是可以互换的,但它是一个陷阱。如果你不加选择地混合使用这两种值,你最终可以将两个Integer值与==进行比较,或者试图在没有意识到的情况下取消空值。由此产生的错误可能是间歇性的,很难追查。

It doesn't help that comparing boxed primitives with == sometimes works as if it were doing a value comparison. It's an illusion caused by the fact that values within a certain range are automatically cached in the process of autoboxing. It's the same problem we've always had with String values: comparing them with == sometimes "works" because you're actually comparing two references to the same, cached object.

将盒装基元与==进行比较有时无助于进行值比较。这是一种错觉,这是由于某个范围内的值在自动装箱过程中自动缓存的事实造成的。这与我们对String值一直存在的问题相同:将它们与==进行比较有时“工作”,因为您实际上是在比较对同一个缓存对象的两个引用。

When dealing with strings we can just tell the n00bs never to compare them with ==, as we've been doing all along. But comparing primitives with == is perfectly valid; the trick (thanks to autoboxing) is being sure the values really are primitives. The compiler will now let us declare a variable as an Integer and use it as if it were an int; that means we have to exercise a greater level of discipline and treat it as an error when someone does so without good reason.

在处理字符串时,我们可以告诉n00bs永远不要将它们与==进行比较,就像我们一直在做的那样。但是将原语与==进行比较是完全有效的;诀窍(感谢autoboxing)确保这些值确实是原始的。编译器现在让我们将一个变量声明为一个Integer并使用它就好像它是一个int;这意味着我们必须行使更高水平的纪律,并在没有充分理由的情况下将其视为错误。

#4


2  

Since Java does something called auto-boxing and auto-unboxing, you should use the primitive type int in most cases because of less overhead.

由于Java执行自动装箱和自动拆箱的操作,因此在大多数情况下应使用基本类型int,因为开销较少。

The only time you absolutely need to use Integer is in generics.

你绝对需要使用Integer的唯一时间是泛型。

List<int> list; // won't compile
List<Integer> list; // correct

#5


2  

The general rules I follow when creating an API can be summarized as follows:

我在创建API时遵循的一般规则可归纳如下:

  1. If the method must return an value, use a primitive type
  2. 如果方法必须返回值,请使用基本类型
  3. If the method may not always apply (eg: getRadioId(...) on an object where such an ID may not exist), then return an Integer and specify in the JavaDocs that the method will return null in some cases.
  4. 如果该方法可能并不总是适用(例如:getRadioId(...)在可能不存在此类ID的对象上),则返回一个Integer并在JavaDocs中指定该方法在某些情况下将返回null。

On #2, look out for NPEs when autoboxing. If you have a method defined as:

在#2上,在自动装箱时注意NPE。如果您将方法定义为:

public Integer getValue();

And then call it as follows:

然后按如下方式调用它:

int myValue = getValue();

In the case where getValue() returns null you'll get an NPE without an obvious cause.

在getValue()返回null的情况下,您将获得没有明显原因的NPE。

#6


1  

Rather than calling them "complex types", you'd be best served thinking Integer, Double, etc. as "Classes", and int, double, etc. as "primitives".

而不是称它们为“复杂类型”,你最好将Integer,Double等视为“Classes”,将int,double等视为“原语”。

If you're doing any type of sophisticated math, the Class-based numeric representation like Integer and Double will be cumbersome and slow you down - many math operations can only be done with primitives.

如果您正在进行任何类型的复杂数学运算,那么基于类的数​​字表示(如Integer和Double)将会很麻烦并且会让您失望 - 许多数学运算只能使用基元来完成。

On the other hand, if you're trying to put your numbers into collections like Lists and Maps, those collections can only contain objects - and thus you must use (or convert to) classes like Integer and Double.

另一方面,如果您尝试将数字放入Lists和Maps等集合中,那些集合只能包含对象 - 因此您必须使用(或转换为)类,如Integer和Double。

Personally, I use primitives whenever I can get away with it, and only convert to the Class representations like Integer when it's time to do input or output, and the transport requires those representations.

就个人而言,每当我可以使用它时,我就会使用原语,并且只有在输入或输出时才转换为类似Integer的类表示,并且传输需要这些表示。

However, if you aren't doing any math at all, and instead are just passing the values straight through your code, you might save yourself some trouble by dealing with the Class-based forms (like Integer) exclusively.

但是,如果您根本不进行任何数学运算,而只是直接在代码中传递值,则可以通过专门处理基于类的表单(如Integer)来省去一些麻烦。

#7


0  

I dont think there is any rule as such. I would choose the types over primitives (Integer over int) when I write method signatures, Maps, collections, Data Objects that get passed around. As such I would still like to use Integer instead of int even inside of methods etc. But if you think that is too much trouble (to type extra "eger") then it is okay to use ints for local variables.

我不认为有这样的规则。当我编写方法签名,地图,集合,传递的数据对象时,我会选择基本类型(Integer over int)。因此我仍然希望在方法等内部使用Integer而不是int。但是如果你认为这太麻烦了(输入额外的“eger”)那么可以使用int来表示局部变量。

#8


0  

If you want to setAttribute to session you have to use Object like Integer,Boolean,String in servlets. If you want to use value you can use primitive types. Objects may be null but primitives not. And if you want to compare types for primitives use == but objects use .equals because in object comparision == looks not values it looks if these are the same objects. And using primitives makes faster the code.

如果要将setAttribute设置为session,则必须在servlet中使用Integer,Boolean,String等Object。如果要使用值,可以使用基本类型。对象可以为null,但原语不是。如果你想比较基元的类型,使用==但是对象使用.equals,因为在对象比较中==看起来不是值,它看起来是否是相同的对象。使用原语使代码更快。

#9


0  

One case in which Integer might be prefered is when you are working with a database where numerical entries are allowed to be null, since you wouldn't be able to represent a null value with an int.

可能更喜欢Integer的一种情况是,当您使用数据库时允许数字条目为空时,因为您无法用int表示空值。

But of course if you're doing straight math, then int would be better as others have mentioned due to intuitiveness and less overhead.

但是当然如果你正在进行直接数学运算,那么由于直观性和较少的开销,int会更好。

#10


0  

I think this is a bit late but I wanted to add my opinion just in case.

我认为这有点晚了但我想加以我的意见以防万一。

in some scenarios, it's required to use the wrappers as the lack of a value is different from the default value.

在某些情况下,需要使用包装器,因为缺少值与默认值不同。

example, for one project I worked on, there was a field on screen where the user could enter a double value, the business requirement clearly mentioned that if the user enters a 0 the meaning is different from not entering a value and leaving the field blank and this difference will make an impact later on in a different module. so in this scenario we had to use the Double object, since I cannot represent a lack of value using the primitive; since the primitive will default to 0 which was a valid input for the field.

例如,对于我工作的一个项目,屏幕上有一个字段,用户可以在其中输入双倍值,业务要求明确提到如果用户输入0,则意义不同于不输入值并将该字段留空而这种差异将在以后的不同模块中产生影响。所以在这种情况下我们不得不使用Double对象,因为我无法使用原语来表示缺少值;因为原语将默认为0,这是该字段的有效输入。