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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/564/
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-07-31 10:35:00  来源:igfitidea点击:

What is the difference between an int and an Integer in Java and C#?

提问by CodingWithoutComments

I was reading More Joel on Softwarewhen I came across Joel Spolskysaying something about a particular type of programmer knowing the difference between an intand an Integerin Java/C# (Object-Oriented Programming Languages).

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

So, what is the difference?

那么区别是什么呢?

采纳答案by Matt

In Java,the 'int' type is a primitive, whereas the 'Integer' type is an object.

在 Java 中,'int' 类型是一个原始类型,而 'Integer' 类型是一个对象。

In C#,the 'int' type is the same as System.Int32and is a value type(ie more like the java 'int'). An integer (just like any other value types) can be boxed("wrapped") into an object.

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



The differences between objects and primitives are somewhat beyond the scope of this question, but to summarize:

对象和原语之间的差异有点超出了这个问题的范围,但总结一下:

Objectsprovide facilities for polymorphism, are passed by reference (or more accurately have references passed by value), and are allocated from the heap. Conversely, primitivesare immutable types that are passed by value and are often allocated from the stack.

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

回答by cmcculloh

Well, in Java an int is a primitive while an Integer is an Object. Meaning, if you made a new Integer:

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

Integer i = new Integer(6);

You could call some method on i:

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

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

Whereas with an int:

而使用 int:

int i = 6;

You cannot call any methods on it, because it is simply a primitive. So:

您不能对其调用任何方法,因为它只是一个原始类型。所以:

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

would produce an error, because int is not an object.

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

int is one of the few primitives in Java (along with char and some others). I'm not 100% sure, but I'm thinking that the Integer object more or less just has an int property and a whole bunch of methods to interact with that property (like the toString() method for example). So Integer is a fancy way to work with an int (Just as perhaps String is a fancy way to work with a group of chars).

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

I know that Java isn't C, but since I've never programmed in C this is the closest I could come to the answer. Hope this helps!

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

Integer object javadoc

整数对象 javadoc

Integer Ojbect vs. int primitive comparison

Integer Ojbect 与 int 原始比较

回答by huseyint

In C#, int is just an aliasfor System.Int32, string for System.String, double for System.Doubleetc...

在 C# 中, int 只是for 、 string for 、 double for等的别名...System.Int32System.StringSystem.Double

Personally I prefer int, string, double, etc. because they don't require a using System;statement :) A silly reason, I know...

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

回答by Chris Jester-Young

I'll add to the excellent answers given above, and talk about boxing and unboxing, and how this applies to Java (although C# has it too). I'll use just Java terminology because I am more au faitwith that.

我将补充上面给出的优秀答案,并讨论装箱和拆箱,以及这如何适用于 Java(尽管 C# 也有)。因为我比较,我会用纯Java术语AU既成事实这一点。

As the answers mentioned, intis just a number (called the unboxedtype), whereas Integeris an object (which contains the number, hence a boxedtype). In Java terms, that means (apart from not being able to call methods on int), you cannot store intor other non-object types in collections (List, Map, etc.). In order to store them, you must first box them up in its corresponding boxed type.

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

Java 5 onwards have something called auto-boxingand auto-unboxingwhich allow the boxing/unboxing to be done behind the scenes. Compare and contrast: Java 5 version:

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

Deque<Integer> queue;

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

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

Java 1.4 or earlier (no generics either):

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

Deque queue;

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

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

It must be noted that despite the brevity in the Java 5 version, both versions generate identical bytecode. Thus, although auto-boxing and auto-unboxing are very convenient because you write less code, these operations dohappens behind the scenes, with the same runtime costs, so you still have to be aware of their existence.

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

Hope this helps!

希望这可以帮助!

回答by Lasse V. Karlsen

I'll just post here since some of the other posts are slightly inaccurate in relation to C#.

我只会在这里发帖,因为其他一些帖子在 C# 方面有些不准确。

Correct:intis an alias for System.Int32.
Wrong:floatis not an alias for System.Float, but for System.Single

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

Basically, int is a reserved keyword in the C# programming language, and is an alias for the System.Int32value type.

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

float and Float is not the same however, as the right system type for ''float'' is System.Single. There are some types like this that has reserved keywords that doesn't seem to match the type names directly.

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

In C# there is no difference between ''int'' and ''System.Int32'', or any of the other pairs or keywords/system types, except for when defining enums. With enums you can specify the storage size to use and in this case you can only use the reserved keyword, and not the system runtime type name.

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

Wether the value in the int will be stored on the stack, in memory, or as a referenced heap object depends on the context and how you use it.

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

This declaration in a method:

方法中的此声明:

int i;

defines a variable iof type System.Int32, living in a register or on the stack, depending on optimizations. The same declaration in a type (struct or class) defines a member field. The same declaration in a method argument list defines a parameter, with the same storage options as for a local variable. (note that this paragraph is not valid if you start pulling iterator methods into the mix, these are different beasts altogether)

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

To get a heap object, you can use boxing:

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

object o = i;

this will create a boxed copy of the contents of ion the heap. In IL you can access methods on the heap object directly, but in C# you need to cast it back to an int, which will create another copy. Thus, the object on the heap cannot easily be changed in C# without creating a new boxed copy of a new int value. (Ugh, this paragraph doesn't read all that easily.)

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

回答by Wedge

This has already been answered for Java, here's the C# answer:

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

"Integer" is not a valid type name in C# and "int" is just an alias for System.Int32. Also, unlike in Java (or C++) there aren't any special primitive types in C#, every instance of a type in C# (including int) is an object. Here's some demonstrative code:

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

回答by andnil

Regarding Java 1.5 and autoboxingthere is an important "quirk" that comes to play when comparing Integer objects.

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

In Java, Integer objects with the values -128 to 127 are immutable (that is, for one particular integer value, say 23, all Integer objects instantiated through your program with the value 23 points to the exactsame object).

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

Example, this returns true:

例如,这将返回 true:

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

While this returns false:

虽然这返回假:

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

The == compares by reference (does the variables point to the same object).

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

This result may or may not differ depending on what JVM you are using. The specification autoboxing for Java 1.5 requires that integers (-128 to 127) always box to the same wrapper object.

此结果可能会或可能不会有所不同,具体取决于您使用的 JVM。Java 1.5 的自动装箱规范要求整数(-128 到 127)总是装箱到同一个包装器对象。

A solution? =) One should always use the Integer.equals() method when comparing Integer objects.

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

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

More info at java.netExample at bexhuff.com

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

回答by grom

In Java there are two basic types in the JVM. 1) Primitive types and 2) Reference Types. int is a primitive type and Integer is a class type (which is kind of reference type).

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

Primitive values do not share state with other primitive values. A variable whose type is a primitive type always holds a primitive value of that type.

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

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

An object is a dynamically created class instance or an array. The reference values (often just references) are pointers to these objects and a special null reference, which refers to no object. There may be many references to the same object.

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

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

Also in Java everything is passed by value. With objects the value that is passed is the reference to the object. So another difference between int and Integer in java is how they are passed in method calls. For example in

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

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

The variable twois passed as the primitive integer type 2. Whereas in

变量作为原始整数类型 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);

The variable twois passed as a reference to an object that holds the integer value 2.

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



@WolfmanDragon: Pass by reference would work like so:

@WolfmanDragon:按引用传递的工作方式如下:

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

When increment is called it passes a reference (pointer) to variable a. And the incrementfunction directly modifies variable a.

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

And for object types it would work as follows:

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

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

Do you see the difference now?

你现在看到区别了吗?

回答by Telcontar

One more thing that I don't see in previous answers: In Java the primitive wrappers classes like Integer, Double, Float, Boolean... and String are suposed to be invariant, so that when you pass an instance of those classes the invoked method couldn't alter your data in any way, in opositión with most of other classes, which internal data could be altered by its public methods. So that this classes only has 'getter' methods, no 'setters', besides the constructor.

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

In a java program String literals are stored in a separate portion of heap memory, only a instance for literal, to save memory reusing those instances

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

回答by mP.

In platforms like Java, ints are primitives while Integeris an object which holds a integer field. The important distinction is that primitives are always passed around by value and by definition are immutable.

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

Any operation involving a primitive variable always returns a new value. On the other hand, objects are passed around by reference. One could argue that the point to the object (AKA the reference) is also being passed around by value, but the contents are not.

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