我在阅读《关于软件的更多Joel》时,偶然看到Joel Spolsky说,有一种特殊类型的程序员知道Java/ c#(面向对象编程语言)中int和Integer的区别。

那么,有什么不同呢?


当前回答

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

其他回答

在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);

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


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

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

当increment函数被调用时,它传递一个指向变量a的引用(指针),并且increment函数直接修改变量a。

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

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

现在你看到区别了吗?

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的别名。 错误:float不是System的别名。浮动,但为了系统。单

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

float和float是不一样的,因为float的正确系统类型是system . single。有一些这样的类型,其保留关键字似乎与类型名称不直接匹配。

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

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

方法中的声明:

int i;

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

要获得一个堆对象,你可以使用装箱:

object o = i;

这将在堆上创建I的内容的盒装副本。在IL中,您可以直接访问堆对象上的方法,但在c#中,您需要将其转换回int类型,这将创建另一个副本。因此,在c#中不容易更改堆上的对象,除非创建一个新的int值的新盒装副本。(啊,这段话读起来可不那么容易。)

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

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

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版本很简洁,但两个版本生成的字节码是相同的。因此,尽管自动装箱和自动拆箱非常方便,因为您编写的代码更少,但这些操作确实发生在幕后,具有相同的运行时成本,因此您仍然必须知道它们的存在。

希望这能有所帮助!

Int用于声明原始变量

e.g. int i=10;

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

Integer a = new Integer();