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

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

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

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

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

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

 List intList = new ArrayList(); // Not allowed. List integerList = new ArrayList(); // Allowed. 

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

 // Autoboxing will turn "1", "2", "3" into Integers from ints. List 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规范可以作为这些方法在基元的包装类中的行为的参考。

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

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

  1. 如果方法必须返回值,请使用基本类型
  2. 如果该方法可能并不总是适用(例如:getRadioId(…)在可能不存在此类ID的对象上),则返回一个Integer并在JavaDocs中指定该方法在某些情况下将返回null。

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

 public Integer getValue(); 

然后按如下方式调用它:

 int myValue = getValue(); 

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

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

 List intList = new ArrayList(); int n = Integer.parseInt("123"); 

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

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

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

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

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

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

 List list; // won't compile List list; // correct 

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

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

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

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

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

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

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

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

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

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

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

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