【问题标题】:What is the difference between an int and an Integer in Java and C#?Java 和 C# 中的 int 和 Integer 有什么区别?
【发布时间】:2010-09-05 06:14:44
【问题描述】:

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

那么,有什么区别呢?

【问题讨论】:

  • C# 没有整数类型。

标签: c# java integer int


【解决方案1】:

在 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# 来说也不太合适。阅读本文的人会比以前了解该主题更少
【解决方案2】:

嗯,在 Java 中,int 是原始类型,而 Integer 是对象。意思是,如果你创建了一个新的 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

【讨论】:

  • 我不懂Java,但没有Integer类型,而是Int32,Int64,它们都是值类型的结构。 Primitive 在 C# 中意味着类型由 CLR 团队在 FCL(Framework Class Library)中定义,这就是它们被称为原始的原因。在这种情况下,甚至 Date obj 也被称为原始类型。
【解决方案3】:

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

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

Java 5 及以后的版本具有称为 auto-boxingauto-unboxing 的功能,它们允许在幕后完成装箱/拆箱。对比对比: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 版本很简洁,但两个版本都生成相同的字节码。因此,虽然自动装箱和自动拆箱非常方便,因为您编写的代码更少,但这些操作发生在幕后,运行时成本相同,因此您仍然需要注意它们的存在.

希望这会有所帮助!

【讨论】:

  • Deque 不在 java 1.5 或 1.4 中。它是在 1.6 中添加的。
【解决方案4】:

我将在此处发布,因为其他一些帖子与 C# 相比有些不准确。

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

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

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

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

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

方法中的这个声明:

int i;

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

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

object o = i;

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

【讨论】:

    【解决方案5】:

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

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

    例如,这会返回 true:

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

    虽然返回 false:

    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.netbexhuff.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 参考的绝佳资源!
    【解决方案6】:

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

    变量 two 作为原始整数类型 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 的对象的引用传递。


    @狼人龙: 通过引用传递将像这样工作:

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

    当调用增量时,它将一个引用(指针)传递给变量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
    

    你现在看出区别了吗?

    【讨论】:

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

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

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

    【讨论】:

    • 而且应该补充一点,C#的int/Int32与Java的Integer相同。
    【解决方案8】:

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

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

    【讨论】:

      【解决方案9】:

      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”。
      【解决方案10】:

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

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

      【讨论】:

        【解决方案11】:

        int用于声明原始变量

        e.g. int i=10;
        

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

        Integer a = new Integer();
        

        【讨论】:

          【解决方案12】:

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

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

          【讨论】:

          • @peter Mortense,(int a; Integer a; ) 如何影响程序,我的意思是它们在执行过程中如何产生影响。
          【解决方案13】:

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

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

          int x;
          Integer y; 
          

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

          Integer.toString(x);
          

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

          【讨论】:

            【解决方案14】:

            Java:

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

            附: Herbert Schildt 的书被用作参考。

            【讨论】:

              【解决方案15】:

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

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

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

              【讨论】:

                【解决方案16】:

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

                例如:

                int number = 7;
                

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

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

                例如:

                Integer number = new Integer(5);
                

                【讨论】:

                  【解决方案17】:

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

                  【讨论】:

                    【解决方案18】:

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

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

                    【讨论】:

                      【解决方案19】:

                      在 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 基础培训的参考资料。

                      【讨论】:

                        【解决方案20】:

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

                        【讨论】:

                          【解决方案21】:

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

                          Integer value1 = null; //OK
                          
                          int value2 = null      //Error
                          

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

                          (包装类 - Boolean、Character、Byte、Short、Integer、Long、Float、Double)

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

                          【讨论】:

                            【解决方案22】:

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

                            【讨论】:

                              【解决方案23】:

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

                              【讨论】:

                              • 这个问题还有 18 个其他答案。你的添加了其他人错过的东西吗?这从一开始就不符合语法并没有帮助。
                              【解决方案24】:

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

                              【讨论】:

                                【解决方案25】:

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

                                【讨论】:

                                  【解决方案26】:

                                  (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...}
                                  

                                  【讨论】:

                                    猜你喜欢
                                    • 2011-03-26
                                    • 2010-11-19
                                    • 2015-01-29
                                    • 2013-09-21
                                    • 2010-10-15
                                    • 1970-01-01
                                    • 2010-09-12
                                    • 2015-05-31
                                    • 2016-12-15
                                    相关资源
                                    最近更新 更多