271

当我遇到Joel Spolsky说一些特定类型的程序员知道Java/C#(面向对象编程语言)中的 an和 an之间的区别时,我正在阅读更多 Joel on Software 。intInteger

那么区别是什么呢?

4

26 回答 26

253

在 Java 中, “int”类型是原始类型,而“Integer”类型是对象。

在 C# 中, 'int' 类型与值类型相同System.Int32并且是值类型(即更像 java 'int')。整数(就像任何其他值类型一样)可以装箱(“包装”)到对象中。


对象和原语之间的区别在某种程度上超出了这个问题的范围,但总结一下:

对象为多态提供了便利,通过引用传递(或者更准确地说是通过值传递引用),并从堆中分配。相反,原语是按值传递的不可变类型,通常从堆栈中分配。

于 2008-08-02T21:55:45.477 回答
155

嗯,在 Java 中,int 是原始类型,而 Integer 是对象。意思是,如果你创建了一个新的整数:

Integer i = new Integer(6);

你可以在 i 上调用一些方法:

String s = i.toString();//sets s the string representation of i

而使用 int:

int i = 6;

你不能在它上面调用任何方法,因为它只是一个原语。所以:

String s = i.toString();//will not work!!!

会产生错误,因为 int 不是对象。

int 是 Java 中为数不多的原语之一(还有 char 和其他一些原语)。我不是 100% 确定,但我认为 Integer 对象或多或少只有一个 int 属性和一大堆与该属性交互的方法(例如 toString() 方法)。所以 Integer 是一种处理 int 的奇特方式(就像 String 可能是处理一组字符的奇特方式一样)。

我知道 Java 不是 C,但由于我从未用 C 编程,这是我能得出的最接近答案的答案。希望这可以帮助!

整数对象 javadoc

整数 Ojbect 与 int 原始比较

于 2008-08-02T22:05:08.093 回答
40

我将补充上面给出的优秀答案,并讨论装箱和拆箱,以及这如何适用于 Java(尽管 C# 也有)。我将只使用 Java 术语,因为我对此更加熟悉

正如上面提到的答案,int只是一个数字(称为未装箱类型),而是Integer一个对象(包含数字,因此是装箱类型)。用 Java 术语来说,这意味着(除了不能在 上调用方法int),您不能在集合(、、等)中存储或其他int非对象类型。为了存储它们,您必须首先将它们装入相应的盒装类型中。ListMap

Java 5 以后有一些称为自动装箱自动拆箱的东西,它允许装箱/拆箱在幕后完成。比较对比: Java 5 版本:

Deque<Integer> queue;

void add(int n) {
    queue.add(n);
}

int remove() {
    return queue.remove();
}

Java 1.4 或更早版本(也没有泛型):

Deque queue;

void add(int n) {
    queue.add(Integer.valueOf(n));
}

int remove() {
    return ((Integer) queue.remove()).intValue();
}

必须注意,尽管 Java 5 版本很简洁,但两个版本都生成相同的字节码。因此,尽管自动装箱和自动拆箱非常方便,因为您编写的代码更少,但这些操作确实发生在幕后,运行时成本相同,因此您仍然必须了解它们的存在。

希望这可以帮助!

于 2008-08-03T02:32:50.690 回答
29

我将在这里发帖,因为其他一些帖子相对于 C# 有点不准确。

正确: intSystem.Int32.
错误: float不是 的别名System.Float,而是System.Single

基本上,int 是 C# 编程语言中的保留关键字,是System.Int32值类型的别名。

但是,float 和 Float 并不相同,因为 '' float'' 的正确系统类型是 System.Single。有一些像这样的类型具有保留关键字,这些关键字似乎与类型名称不直接匹配。

int在 C# 中,'' '' 和 '' '' 或任何其他对或关键字/系统类型之间没有区别System.Int32,定义枚举时除外。使用枚举,您可以指定要使用的存储大小,在这种情况下,您只能使用保留关键字,而不是系统运行时类型名称。

int 中的值是存储在堆栈中、内存中还是作为引用的堆对象取决于上下文以及您如何使用它。

方法中的此声明:

int i;

根据优化定义一个i类型的变量,存在于寄存器或堆栈中。System.Int32类型(结构或类)中的相同声明定义了一个成员字段。方法参数列表中的相同声明定义了一个参数,具有与局部变量相同的存储选项。(请注意,如果您开始将迭代器方法混入其中,则本段无效,这些完全是不同的野兽)

要获取堆对象,可以使用装箱:

object o = i;

i这将在堆上创建内容的盒装副本。在 IL 中,您可以直接访问堆对象上的方法,但在 C# 中,您需要将其转换回 int,这将创建另一个副本。因此,如果不创建新 int 值的新盒装副本,就无法在 C# 中轻松更改堆上的对象。(呃,这一段读起来并不容易。)

于 2008-08-04T14:11:03.557 回答
21

关于 Java 1.5 和自动装箱,在比较 Integer 对象时会出现一个重要的“怪癖”。

在 Java 中,值为 -128 到 127 的 Integer 对象是不可变的(也就是说,对于一个特定的整数值,比如 23,通过程序实例化的值为 23 的所有 Integer 对象都指向完全相同的对象)。

例如,这将返回 true:

Integer i1 = new Integer(127);
Integer i2 = new Integer(127);
System.out.println(i1 == i2); //  true

虽然这返回错误:

Integer i1 = new Integer(128);
Integer i2 = new Integer(128);
System.out.println(i1 == i2); //  false

== 通过引用进行比较(变量是否指向同一个对象)。

根据您使用的 JVM,此结果可能会有所不同,也可能不会有所不同。Java 1.5 的规范自动装箱要求整数(-128 到 127)始终装箱到同一个包装器对象。

一个办法?=) 在比较 Integer 对象时,应始终使用 Integer.equals() 方法。

System.out.println(i1.equals(i2)); //  true

更多信息在java.net上的例子bexhuff.com

于 2008-08-05T20:49:13.017 回答
20

在 Java 中, JVM中有两种基本类型。1) 原始类型和 2) 引用类型。int 是原始类型,而 Integer 是类类型(这是一种引用类型)。

原始值不与其他原始值共享状态。类型为原始类型的变量始终保存该类型的原始值。

int aNumber = 4;
int anotherNum = aNumber;
aNumber += 6;
System.out.println(anotherNum); // Prints 4

对象是动态创建的类实例或数组。引用值(通常只是引用)是指向这些对象的指针和一个特殊的空引用,它不引用任何对象。可能有许多对同一对象的引用。

Integer aNumber = Integer.valueOf(4);
Integer anotherNumber = aNumber; // anotherNumber references the 
                                 // same object as aNumber

同样在 Java 中,一切都是按值传递的。对于对象,传递的值是对对象的引用。所以java中int和Integer之间的另一个区别是它们是如何在方法调用中传递的。例如在

public int add(int a, int b) {
    return a + b;
}
final int two = 2;
int sum = add(1, two);

变量2作为原始整数类型 2 传递。而在

public int add(Integer a, Integer b) {
    return a.intValue() + b.intValue();
}
final Integer two = Integer.valueOf(2);
int sum = add(Integer.valueOf(1), two);

变量2作为对包含整数值 2 的对象的引用传递。


@WolfmanDragon:通过引用传递会像这样工作:

public void increment(int x) {
  x = x + 1;
}
int a = 1;
increment(a);
// a is now 2

当调用 increment 时,它会将引用(指针)传递给变量a。而增量函数直接修改变量a

对于对象类型,它的工作方式如下:

public void increment(Integer x) {
  x = Integer.valueOf(x.intValue() + 1);
}
Integer a = Integer.valueOf(1);
increment(a);
// a is now 2

你现在看到区别了吗?

于 2008-08-06T11:08:52.283 回答
11

在 C# 中,int 只是 的别名System.Int32string的别名System.String,double的别名System.Double等...

就我个人而言,我更喜欢 int、string、double 等,因为它们不需要using System;声明:) 一个愚蠢的理由,我知道......

于 2008-08-02T23:37:10.077 回答
10

使用包装类的原因有很多:

  1. 我们得到额外的行为(例如我们可以使用方法)
  2. 我们可以存储空值,而在原语中我们不能
  3. 集合支持存储对象而不是原语。
于 2014-07-31T10:07:55.403 回答
8

Java 已经回答了这个问题,这是 C# 的答案:

“Integer”不是 C# 中的有效类型名称,“int”只是 System.Int32 的别名。此外,与 Java(或 C++)不同,C# 中没有任何特殊的原始类型,C# 中类型的每个实例(包括 int)都是一个对象。这是一些演示代码:

void DoStuff()
{
    System.Console.WriteLine( SomeMethod((int)5) );
    System.Console.WriteLine( GetTypeName<int>() );
}

string SomeMethod(object someParameter)
{
    return string.Format("Some text {0}", someParameter.ToString());
}

string GetTypeName<T>()
{
    return (typeof (T)).FullName;
}
于 2008-08-04T21:02:54.910 回答
8

我在以前的答案中没有看到的另一件事:在 Java 中,原始包装类(如 Integer、Double、Float、Boolean... 和 String)被认为是不变的,因此当您传递这些类的实例时,调用的方法不能以任何方式更改您的数据,与大多数其他类相反,其内部数据可以通过其公共方法更改。因此,除了构造函数之外,这些类只有“getter”方法,没有“setter”。

在Java程序中,字符串文字存储在堆内存的单独部分中,只有文字的一个实例,以节省内存重用这些实例

于 2008-08-06T14:33:33.090 回答
8

在像 Java 这样的平台中,ints 是原语,而 sInteger是一个包含整数字段的对象。重要的区别是原语总是按值传递,并且根据定义是不可变的。

任何涉及原始变量的操作总是返回一个新值。另一方面,对象是通过引用传递的。有人可能会争辩说,指向对象的点(也称为引用)也是按值传递的,但内容不是。

于 2009-01-31T02:49:09.053 回答
8

int 用于声明原始变量

e.g. int i=10;

Integer 用于创建 Integer 类的引用变量

Integer a = new Integer();
于 2011-12-11T07:19:32.320 回答
7

在此之前您是否编程过 (int) 是您可以为变量设置的原始类型之一(就像 char、float 等)。

但是 Integer 是一个包装类,您可以使用它对 int 变量执行一些功能(例如将其转换为字符串或反之亦然,...),但请注意包装类中的方法是静态的,因此您可以使用它们任何时候都无需创建 Integer 类的实例。作为回顾:

int x;
Integer y; 

x 和 y 都是 int 类型的变量,但是 y 被一个 Integer 类包装,并且有几个你可以使用的方法,但是如果你需要调用 Integer 包装类的一些函数,你可以简单地做到这一点。

Integer.toString(x);

但请注意 x 和 y 都是正确的,但如果您只想将它​​们用作原始类型,请使用简单形式(用于定义 x)。

于 2014-05-17T11:56:58.703 回答
7

爪哇:

int, double, long, byte, float, double, short, boolean, char- 基元。用于保存语言支持的基本数据类型。原始类型不是对象层次结构的一部分,它们不继承 Object。Thet can'be pass by reference to a method。

Double, Float, Long, Integer, Short, Byte, Character, 和Boolean, 是类型 Wrappers,封装在java.lang. 所有数字类型包装器都定义了允许从给定值或该值的字符串表示构造对象的构造函数。即使是最简单的计算,使用对象也会增加开销。

从 JDK 5 开始,Java 包含了两个非常有用的特性:自动装箱和自动拆箱。自动装箱/拆箱极大地简化了必须将原始类型转换为对象的代码,反之亦然。

构造函数示例:

Integer(int num)
Integer(String str) throws NumberFormatException
Double(double num)
Double(String str) throws NumberFormatException

装箱/拆箱示例:

class ManualBoxing {
        public static void main(String args[]) {
        Integer objInt = new Integer(20);  // Manually box the value 20.
        int i = objInt.intValue();  // Manually unbox the value 20
        System.out.println(i + " " + iOb); // displays 20 20
    }
}

自动装箱/自动拆箱示例:

class AutoBoxing {
    public static void main(String args[]) {
        Integer objInt = 40; // autobox an int
        int i = objInt ; // auto-unbox
        System.out.println(i + " " + iOb); // displays 40 40
    }
}

PS Herbert Schildt 的书被作为参考。

于 2016-06-13T19:31:43.493 回答
4

在两种语言(Java 和 C#)int中都是 4 字节有符号整数。

与 Java 不同,C# 提供有符号和无符号整数值。由于 Java 和 C# 是面向对象的,因此这些语言中的某些操作不会直接映射到运行时提供的指令上,因此需要将其定义为某种类型的对象的一部分。

C#System.Int32使用属于堆上的引用类型的一部分内存提供了哪个值类型。

java 提供java.lang.Integer了在int. 中的方法Integer不能直接编译为运行时指令。因此我们将一个 int 值装箱以将其转换为 Integer 的实例,并使用需要某种类型实例的方法(如toString()parseInt()valueOf())。

在 C# 中,变量 int 是指System.Int32.Any内存中的 4 字节值,可以解释为原始 int,可以通过 System.Int32 的实例进行操作。所以 int 是System.Int32.When使用整数相关方法的别名,如int.Parse()int.ToString()。整数被编译成FCLSystem.Int32结构调用相应的方法,如Int32.Parse(), Int32.ToString()

于 2014-07-17T06:02:03.273 回答
4

Java 和 C# 中的 int 和 Integer 是用于表示不同事物的两个不同术语。它是可以分配给可以精确存储的变量的原始数据类型之一。一次其声明类型的一个值。

例如:

int number = 7;

int分配给包含值 7 的变量 number 的数据类型在哪里。所以 anint只是一个原语而不是一个对象。

而 anInteger是具有静态方法的原始数据类型的包装类。这可以用作需要对象的方法的参数,而 int 可以用作需要整数值的方法的参数,可以用于算术表达式。

例如:

Integer number = new Integer(5);
于 2014-08-07T10:50:29.320 回答
4

一个 int 变量保存一个 32 位有符号整数值。Integer(大写 I)持有对(类)类型 Integer 或 null 的对象的引用。

Java 自动在两者之间进行转换;每当 Integer 对象作为 int 运算符的参数出现或分配给 int 变量,或将 int 值分配给 Integer 变量时,从 Integer 到 int。这种铸造称为装箱/拆箱。

如果引用 null 的 Integer 变量被显式或隐式拆箱,则会引发 NullPointerException。

于 2015-11-26T10:54:15.217 回答
4

在 Java 中,int类型是原始数据类型,而Integer类型是对象。

在 C# 中,int类型也是与System.Int32. An integer(就像任何其他值类型一样)可以装箱(“包装”)到对象中。

于 2017-04-27T07:25:54.037 回答
3

在 Java 中,int 是一种原始数据类型,而 Integer 是一个 Helper 类,它用于将一种数据类型转换为另一种数据类型。

例如:

double doubleValue = 156.5d;
Double doubleObject  = new Double(doubleValue);
Byte myByteValue = doubleObject.byteValue ();
String myStringValue = doubleObject.toString();

原始数据类型存储了 Helper 类复杂的最快可用内存,并存储在 heep 内存中。

来自“David Gassner”Java Essential Training 的参考资料。

于 2016-02-28T18:42:46.323 回答
2

“int”是 Java 中 Wrapper Class 中的原始数据类型和“Integer”。“整数”可以用作需要对象的方法的参数,而“int”可以用作需要整数值的方法的参数,可用于算术表达式。

于 2017-08-04T09:57:22.740 回答
1

int在库函数c#中预定义但在java中我们可以创建对象Integer

于 2017-03-06T05:08:39.983 回答
1

01.整数可以为空。但 int 不能为空。

Integer value1 = null; //OK

int value2 = null      //Error

02. 只能将 Wrapper Classes 类型值传递给任何集合类。

(包装类 - 布尔型、字符型、字节型、短型、整数型、长型、浮点型、双精度型)

List<Integer> element = new ArrayList<>();
int valueInt = 10;
Integer  valueInteger = new Integer(value);
element.add(valueInteger);

但是通常我们将原始值添加到集合类中?第02点正确吗?

List<Integer> element = new ArrayList<>();
element.add(5);

是的 02 是正确的,因为autoboxing.

自动装箱是 Java 编译器在原始类型与其对应的包装类之间进行的自动转换。

然后 5 通过自动装箱转换为整数值。

于 2018-06-05T11:35:14.763 回答
0

根据我的知识,如果你在 java 中学习,那么当你写 int a; 然后在 java 泛型中它会编译像Integer a = new Integer(). 因此,根据泛型Integer不使用但int使用。所以那里有如此大的差异。

于 2016-09-22T09:53:52.680 回答
0

(Java 版本)简单来说int是原始的(不能有空值),整数是 int 的包装对象。

一个使用 Integer 与 int 的示例,当您想再次比较和 int 变量 null 时,它会抛出错误。

int a;
//assuming a value you are getting from data base which is null
if(a ==null) // this is wrong - cannot compare primitive to null
{
do something...}

Instead you will use,
Integer a;
//assuming a value you are getting from data base which is null
if(a ==null) // this is correct/legal
{ do something...}
于 2018-02-15T21:04:45.903 回答
0

int是原始数据类型。 Integer是一个包装类。它可以将 int 数据存储为对象。

于 2019-06-03T07:01:04.717 回答
0

int 是原始数据类型,而 Integer 是对象。使用 Integer 创建对象将使您能够访问 Integer 类中可用的所有方法。但是,如果您使用 int 创建原始数据类型,您将无法使用这些 inbuild 方法,您必须自己定义它们。但是,如果您不想要任何其他方法并希望使程序更节省内存,则可以使用原始数据类型,因为创建对象会增加内存消耗。

于 2019-07-03T05:35:18.697 回答