ChatGPT解决这个技术问题 Extra ChatGPT

Java 和 C# 中的 int 和 Integer 有什么区别?

我在阅读 More Joel on Software 时遇到 Joel Spolsky 说某类特定类型的程序员知道 Java/C#(面向对象编程)中 intInteger 之间的区别语言)。

那么区别是什么呢?

C# 没有整数类型。

F
Fred

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

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

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

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


IMO,“对象 [...] 通过引用传递”的说法令人困惑且不正确。更准确的说法是“对象引用是按值传递的”。 (此外,原语并不总是从堆栈中分配 - 考虑对象中的原语字段......)
至少在 C# 中,int 是相当于 Int32 CLR(实际上是 CTS)类型的语言关键字。
抱歉,英语没有使“通过引用传递某物”和“通过值传递对某事物的引用”等价语句,这些在编程语言上下文中也没有等价的含义。
‒1。这可能准确地描述了 Java 是如何处理这个问题的,但对于 C# 来说这是完全错误的。
为什么这被投票赞成?答案是错误的。这对于 Java 来说并不完全正确,对于 C# 来说甚至更接近正确。读过这篇文章的人对这个话题的了解会比以前少。
A
Afshin Moazami

嗯,在 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 编程,这是我能得出的最接近答案的答案。希望这可以帮助!

Integer object javadoc

Integer Ojbect vs. int primitive comparison


在 C# 中,int 是 Int32 的同义词,请参阅 stackoverflow.com/questions/62503/c-int-or-int32-should-i-care
我不知道Java,但没有类型Integer,而是Int32,Int64,它们都是值类型的结构。 Primitive 在 C# 中意味着类型是由 CLR 团队在 FCL(Framework Class Library)中定义的,这就是它们被称为原始类型的原因。在这种情况下,甚至 Date obj 也被称为原始类型。
F
Fred

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

正如上面提到的答案,int 只是一个数字(称为 unboxed 类型),而 Integer 是一个对象(包含数字,因此是 boxed 类型)。在 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 版本很简洁,但两个版本都生成相同的字节码。因此,尽管自动装箱和自动拆箱非常方便,因为您编写的代码更少,但这些操作确实发生在幕后,运行时成本相同,因此您仍然必须了解它们的存在。

希望这可以帮助!


双端队列不在 java 1.5 或 1.4 中。它是在 1.6 中添加的。
H
H. Pauwelyn

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

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

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

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

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

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

方法中的此声明:

int i;

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

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

object o = i;

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


a
andynil

关于 Java 1.5 和 autoboxing,在比较 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 中的示例


与 == 比较时,使用 new 运算符创建的对象将始终返回 false。 Andreas 将 Integer.valueOf(int) 与 new Integer(int) 混淆了
注意:默认值 127 取自 sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
@andnil - 我曾经在 Stellent 与 Bex 一起工作。他是引用 +1 以供 bexhuff.com 参考的非常棒的资源!
g
grom

在 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

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

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

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

你现在看到区别了吗?


根据您的定义,没有通过引用传递。任何传递的东西都必须有一个值(即使 null 也是一个值),即使它只是指针的一个值,否则它只是一个空集。通过 CS 术语,按引用传递是传递引用(指针)的值。我有点困惑。?
A
Ahmad

在 C# 中,int 只是 System.Int32aliasSystem.String 的字符串、System.Double 的双精度等...

我个人更喜欢 int、string、double 等,因为它们不需要 using System; 语句:) 一个愚蠢的原因,我知道......


而且应该补充一点,C#的int/Int32和Java的Integer是不一样的。
M
Matthew Haugen

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

我们得到额外的行为(例如我们可以使用方法)我们可以存储空值,而在原语中我们不能集合支持存储对象而不是原语。


W
Wedge

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

需要明确的是,在 C# 中,int 和 System.Int32 都不是对象。它们是值类型,CLR 对它们的处理方式与对象大不相同。
实际上,在 C# 中 Int32 是一个对象。它是派生自 system.object 的值类型结构对象。它与其他值对象的处理方式并没有特别不同,因为 Java 中的“int”。
J
Jim Anderson

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

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


n
nagarajn89

int 用于声明原始变量

e.g. int i=10;

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

Integer a = new Integer();

P
Peter Mortensen

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

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


@peter Mortense, (int a; Integer a; ) 如何影响程序,我的意思是它们在执行过程中如何产生影响。
T
Tomasz Jakub Rup

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

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

int x;
Integer y; 

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

Integer.toString(x);

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


J
J-Alex

爪哇:

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

DoubleFloatLongIntegerShortByteCharacterBoolean 是封装在 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 的书被作为参考。


佚名

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

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

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


H
H. Pauwelyn

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

例如:

int number = 7;

其中 int 是分配给变量 number 的数据类型,该变量包含值 7。所以 int 只是一个原语而不是一个对象。

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

例如:

Integer number = new Integer(5);

j
jalopaba

在两种语言(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 的别名,使用与整数相关的方法,如 { 3}、int.ToString() 等。整数被编译到 FCL System.Int32 结构中,调用相应的方法,如 Int32.Parse()Int32.ToString()


C
Clijsters

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

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


T
Tomasz Jakub Rup

在 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 的参考资料。


M
MD RAHIIM

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


P
Priyantha

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 通过自动装箱转换为整数值。


d
developerick

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


d
developerick

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


这个问题还有 18 个其他答案。你的添加了其他人错过的东西吗?这从一开始就不符合语法,这无济于事。
K
Kavinda Pushpitha

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


L
Lourdes

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


R
Rishabh Agarwal

(Java 版)简单来说 int 是原始的(不能有空值),而 Integer 是 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...}