这两条线有什么区别?
int pInt = 500;
和
Integer wInt = new Integer(pInt);
或者
Integer wInt = new Integer(500);
这两条线有什么区别?
int pInt = 500;
和
Integer wInt = new Integer(pInt);
或者
Integer wInt = new Integer(500);
没有任何。
那是完全相同的事情。在第一种情况下,您只有一个补充变量。
请注意,使用自动装箱,您很少需要同时拥有 anint
和 anInteger
变量。所以对于大多数情况,这已经足够了:
int pInt = 500;
Integer 有用的主要情况是区分变量未知的情况(即null
):
Integer i = null; // possible
int i = null; // not possible because only Object variables can be null
但是不要保留两个变量,一个就足够了。
在 Java 中,原始类的实例保存实例的实际值,但包装类的实例保存对对象的引用。即可以找到对象的位置的地址。
当您使用这一行编写程序时:
Integer integer = 500;
编译器将其更改为:
Integer integer = new Integer(500);
这个过程称为自动装箱。这会自动将原始实例放入整数的“盒子”中。因此,以下程序的输出:
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
,但不是 on i
。也就是说:包装器的对象可以被取消引用,但不能是原始实例。
装箱和拆箱可能会稍微减慢程序的速度。因此,对于新手来说,包装器可能看起来像是增加了负担,但事实并非如此。包装器用于对象需要是引用类型的地方。eg:Map<Integer,String>map=new HashMap<Integer,String>();
是一个有效的陈述,但Map<int,String>map=new HashMap<int,String>();
不是一个有效的陈述。
包装器非常有用的另一个典型情况:
在 MySQL 中,NULL
它是INT
类型列的有效条目。但是在Java中,int
不能有null
值,Integer
可以。这是因为在 SQL 中NULL
表示Not Available。因此,如果您使用 JDBC 在 MySQL 表中插入整数值,null
您的 java 程序中的 a 将有助于在NULL
MySQL 表中插入。
包装类在与此类似或类似的情况下也很有用:
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
对于初学者
int pInt = 500;
, 这里pInt
不是一个对象,而在
Integer wInt = new Integer(500);
wInt
是参考
这也是java不是纯面向对象语言的一个原因。因为一切都不是java的对象。
除非您需要对象,否则您应该使用原始类型。
包装类可以是null
原始类型,例如:Integer
可以null
,int
不能。
这是原始数据类型初始化:
int pInt = 500;
这是为相同的原始数据类型创建包装类:
Integer wInt = new Integer(pInt);
Java API 中的包装类有两个主要用途:
在Java 1.5中有一个称为Autoboxing的概念。它具有在对象包装器与其原始类型之间进行转换或转换的能力。
所以这意味着:
Integer wInt = 500;
int pInt = new Integer(500);
由于自动装箱,这可能是可能的。
Wrapper 类将在该框中有一个框,它将覆盖原始数据类型,有 8 种原始数据类型,即 byte、int、long、double、float、short、Boolean 和 char,这些都包含在 wrapper 类中。
使用我们使用的原始数据类型,例如 int a;
但是要使用包装类,我们需要使用 likeInteger a = new Integer(i);
数据的类型是相同的,但在某些情况下,对象的操作比原始类型(如数据结构)更方便,您需要对数据类型进行更多控制。
例如,对象可以为空,而原始类型不能。
您也不能调用原始类型(.compareTo()、.equals()、...)的方法,但可以在包装类中调用。
以下信息描述了原始类和包装类中的类型:
原始类型 | 包装类(超类 = 对象)
原始类型 | 包装类(超类=数字)
要了解 wapper 类的工作原理,请考虑以下示例:
public final class IntWrapper {
private final int intVal;
IntWrapper(int intVal) {
this.intVal = intVal;
}
public int getInt() {
return intVal;
}
}
现在我们可以从我们的新 IntWrapper 类中创建一个对象,并“装箱”原始 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 的。
重要的是要注意,当 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 集合(仅接受对象)中提供的数据结构中插入值,现在存在自动装箱或装箱和自动拆箱或拆箱选项。
自动装箱或装箱允许您插入原始值以引用等效的包装器类型或对象类型:
// 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 是 Integer 时完成循环需要 138 ms(平均超过 50 次试验),但当 ix 是 int 时只需要 10 ms