何时使用原始类型以及何时在 Java 中引用类型

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2509025/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 21:33:40  来源:igfitidea点击:

When to use primitive and when reference types in Java

javaprimitive-typesreference-type

提问by Gandalf StormCrow

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

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

This questionsparked my curiosity.

这个问题激发了我的好奇心。

回答by coobird

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

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

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 Integeris in the case of using generics, as Java does not support the use of primitive types as type parameters:

其中一种情况是必须使用包装类,例如Integer在使用generics的情况下,因为 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 valueOfmethod 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 valueOfmethods, the API specification for the Integer.valueOfmethod can serve as a reference for how those methods will behave in the wrapper classes for primitives.

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

回答by BalusC

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).

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

回答by Jason Nichols

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

我在创建 API 时遵循的一般规则可以总结如下:

  1. If the method mustreturn an value, use a primitive type
  2. 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.
  1. 如果方法必须返回值,请使用原始类型
  2. 如果该方法可能并不总是适用(例如: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。

回答by jjnguy

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

由于 Java 做了一些称为auto-boxing 和 auto-unboxing 的事情,因此int在大多数情况下您应该使用原始类型,因为开销较少。

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

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

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

回答by Alan Moore

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 程序员的建议。随着他们学习的更多,他们会遇到必须更加敏锐的情况,比如在处理 Maps 或数据库时,但到那时他们也应该更好地理解基元和盒装基元之间的区别。

Autoboxing tempts us to believe intand 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 nullwithout realizing it. The resulting bugs can be intermittent and difficult to track down.

自动装箱诱使我们相信intInteger(例如)可以互换,但这是一个陷阱。如果您不加选择地混合这两种值,您最终==可能会在null没有意识到的情况下将两个 Integer 值与a进行比较或尝试拆箱。由此产生的错误可能是间歇性的,并且难以追踪。

It doesn't help that comparing boxed primitives with ==sometimesworks 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 Integerand 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 永远不要将它们与 进行比较==,就像我们一直在做的那样。但是将原语与 比较==是完全有效的;诀窍(由于自动装箱)是确保这些值确实是基元。编译器现在让我们将变量声明为 anInteger并像使用int;一样使用它。这意味着我们必须加强纪律并将其视为错误,如果有人没有正当理由这样做。

回答by Glenn Barnett

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 等视为“类”,将 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),您可能会省去一些麻烦。

回答by user300943

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.

如果要将属性设置为会话,则必须在 servlet 中使用诸如 Integer、Boolean、String 之类的对象。如果你想使用值,你可以使用原始类型。对象可能为空,但原语不是。如果你想比较基元的类型使用 == 但对象使用 .equals 因为在对象比较中 == 看起来不是值,如果这些是相同的对象,它看起来。使用原语可以加快代码速度。

回答by FromCanada

One case in which Integermight 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 intwould be better as others have mentioned due to intuitiveness and less overhead.

但是,当然,如果您正在做直接的数学运算,那么int由于直观性和更少的开销,就像其他人提到的那样会更好。

回答by ahmad alzamer

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,这是该字段的有效输入。

回答by Anas

When we deal with Spring getRequest mapping methods, using boolean value does not work.

当我们处理 Spring getRequest 映射方法时,使用布尔值是行不通的。

For instance :

例如 :

@GetMapping("/goal")
public boolean isValidGoal() { 
    boolean isValid = true;
    return isValid;
}

Always opt for Boolean in those cases.

在这些情况下总是选择布尔值。