原始类型和包装类之间的主要区别是什么?

这两行有什么区别?

int pInt = 500; 

  Integer wInt = new Integer(pInt); 

要么

  Integer wInt = new Integer(500); 

没有。

那是完全一样的。 在第一种情况下,您只有一个补充变量。

请注意,使用自动装箱,您很少需要同时拥有intInteger变量。 所以对于大多数情况来说这就足够了:

 int pInt = 500; 

Integer有用的主要情况是区分变量未知的情况(即null ):

 Integer i = null; // possible int i = null; // not possible because only Object variables can be null 

但是不要保留两个变量,一个就足够了。

对于初学者

int pInt = 500; ,这里pInt不是一个对象,而在

Integer wInt = new Integer(500); wInt是一个参考

这也是java不是纯面向对象语言的原因。 因为一切都不是java的对象。

在Java中,primitve类的实例保存实例的实际值,但包装类的实例保存对该对象的引用。 即找到对象的地方的地址。

当您使用此行编写程序时:

 Integer integer = 500; 

编译器将其更改为:

 Integer integer = new Integer(500); 

此过程称为自动装箱 。 这是自动将原始实例放在Integer的“框”中。 因此,输出以下程序:

 public class PrimitiveToObject { public static void main(String[] args) { printClassName(1); printClassName(1L); printClassName((char)1); } public static void printClassName(Object object){ System.out.println(object.getClass()); } } 

这是:

 class java.lang.Integer class java.lang.Long class java.lang.Character 

这个:

 int i = integer; 

变成这个:

 int i = integer.intValue(); 

这称为拆箱

如上所示, 点运算符. )用于名为integer的变量,但不用于i 。 也就是说:包装器的对象可以被解除引用 ,但不能是原始实例。

拳击和拆箱可能会减慢程序的速度。 因此,对于一个新手来说,包装可能看起来像增加了负担,但事实并非如此。 包装器用于对象需要作为引用类型的位置。 例如: Mapmap=new HashMap(); 是一个有效的语句,但Mapmap=new HashMap(); 不是有效的声明。

包装器非常有用的另一个典型案例:
在MySQL中, NULLINT类型列的有效条目。 但是在Java中, int不能null值, Integer可以。 这是因为在SQL中, NULL表示不可用 。 因此,如果您使用JDBC在MySQL表中插入整数值,则java程序中的null将有助于在MySQL表中插入NULL

在与此类似或相似的情况下,包装类也可能有用:

 Boolean decision; // Using wrapper for boolean. if("YES".equalsIgnoreCase(consent)) decision = Boolean.TRUE; // In favour else if("NO".equalsIgnoreCase(consent)) decision = Boolean.FALSE; // Not in favour else if("CAN'T SAY".equalsIgnoreCase(consent)) decision = null; // Undecided 

除非需要对象,否则应使用基本类型。
包装类可以为null但是原始类型Ex: Integer可以为nullint不能。

这是原始数据类型初始化:

 int pInt = 500; 

这是为相同的原始数据类型创建包装类:

 Integer wInt = new Integer(pInt); 

Java API中的包装类有两个主要用途:

  • 提供一种机制来“包装”对象中的原始值,以便原语可以包含在为对象保留的活动中,例如添加到集合中,或者从具有对象返回值的方法返回。
  • 为基元提供各种实用程序function。 这些函数中的大多数与各种转换有关:将原语转换为String对象,以及将原语和String对象转换为不同的基数(或基数),例如二进制,八进制和hex。

Java 1.5中,有一个名为Autoboxing的概念。 它具有在对象包装器和它的原始类型之间转换或转换的能力。

这意味着:

 Integer wInt = 500; int pInt = new Integer(500); 

由于Autoboxing,它可能是可能的。

包装类将在该框中有一个框,它将覆盖原始数据类型,有8种原始数据类型,即byte,int,long,double,float,short,Boolean,char这些都包含在包装类中。

使用我们使用的原始数据类型,如int a;

但要使用包装类,我们需要像Integer a = new Integer(i);一样使用Integer a = new Integer(i);

数据类型是相同的,但有些情况下,对象的操作比原始类型(如数据结构)更方便,您需要更多地控制数据类型。
例如,对象可以为null,而基本类型则不能。
您也不能以原始类型(.compareTo(),. equals(),…)调用方法,但在包装类中可以。

以下信息描述了原始类和包装类中的类型:

原始类型| 包装类(超类=对象)

  • 布尔值 – 布尔值
  • char – 角色

原始类型| 包装类(超类=数字)

  • 字节 – 字节
  • 短 – 短
  • int – 整数
  • 龙 – 龙
  • 浮 – 浮
  • 双 – 双

要了解wapper类的工作原理,请考虑以下示例:

 public final class IntWrapper { private final int intVal; IntWrapper(int intVal) { this.intVal = intVal; } public int getInt() { return intVal; } } 

现在我们可以用新的IntWrapper类创建一个对象,并将’box’作为原始int值41:

 int i = 41; IntWrapper iw = new IntWrapper( i ); // box the primitive int type value into the object i = iw.getInt(); // unbox the value from the wrapper object 

我的示例IntWrapper类是不可变的,不可变的意味着一旦其状态被初始化,其状态就无法改变。 将final关键字应用于类时,无法扩展最终类。 换句话说,final类永远不能是子类的超类。 最后一个类可以是超类的子类,而不是那里的问题。 当一个类被标记为final时,它的所有方法都是隐式最终的。

重要的是要注意,当final应用于引用变量时,它不会阻止对象实例的成员更改值。

这个例子是为了更好地理解包装类如何在里面工作。

接下来,要创建Integer,Double和其他包装类,您可以编写:

 Integer i = new Integer(4); Double d = new Double(9.62); Boolean b = new Boolean("true"); Character c = new Character('M'); 

要将封装的数字放入包装器对象,您可以编写:

 long l = i.longValue(); double e = i.doubleValue(); float f = d.floatValue(); short s = d.shortValue(); 

每个包装类都包含在基本类型和包装器对象之间转换的特殊方法,它们不代表数字值:

 boolean bo = b.booleanValue(); char ch = c.charValue(); 

在Java 5版本中,从包装类创建对象必须使用上面的语法,但是为了简化这些操作,主要涉及在Java集合(仅接受对象)中提供的数据结构中插入值,现在存在自动装箱或装箱和自动装箱或拆箱选项。

autoboxing或boxing允许您插入原始值以引用等效包装类型或对象类型:

 // Same result of Double d = new Double(-2.75); Double objD = -2.75; // Same result of Object objI = new Integer(13); Object objI = 13; 

自动装箱或取消装箱允许您将包装器对象插入到基本类型的变量中,并在等效类型之间自动转换:

 // Same result of double vd = objD.doubleValue(); double vd = objD; // Same result of int vi = objI.intValue(); int vi = objI; 

我看到的最重要的实际差异是Integer初始化和使用int进行计算的速度要慢一些。 除非必要,否则我会避免使用Integer

 int x = 20_000_000;// 20 millions for (int i = 0; i < x; i++) { ix += 23; } 

当ix是整数时,需要138 ms(平均超过50次试验)才能完成循环,但当ix是int时,只需要10 ms