你好!您已经非常熟悉原始类型,并且已经对它们进行了大量的工作。在编程(尤其是 Java)中,基元有很多优点:它们使用很少的内存(因此使程序更高效)并且具有明确界定的值范围。然而,在学习 Java 的过程中,我们已经经常重复“Java 中的一切都是对象”这句口头禅。但是原始人直接与这些话相矛盾。它们不是对象。那么,我们的“一切皆对象”原则是不是错误的呢?其实不然。在 Java 中,每个基本类型都有一个孪生兄弟,一个包装类。
包装器对象的创建方式与任何其他对象相同:
什么是包装类?
包装器是一个在内部存储原语的特殊类。但是因为它是一个类,所以您可以创建它的实例。它们在内部存储原始值,但仍然是真实的对象。包装器类名称与其对应原语的名称非常相似(或完全相同)。因此,它们很容易记住。原始数据类型的包装类 | |
---|---|
原始数据类型 | 包装类 |
整数 | 整数 |
短的 | 短的 |
长的 | 长的 |
字节 | 字节 |
漂浮 | 漂浮 |
双倍的 | 双倍的 |
字符 | 特点 |
布尔值 | 布尔值 |
public static void main(String[] args) {
Integer i = new Integer(682);
Double d = new Double(2.33);
Boolean b = new Boolean(false);
}
包装类让我们减轻了原始类型的缺点。最明显的是原语没有方法。例如,它们没有toString()方法,因此您不能将int转换为String。但是Integer包装器类使这很容易。
public static void main(String[] args) {
Integer i = new Integer(432);
String s = i.toString();
}
但是,向另一个方向转换可能会比较棘手。假设我们有一个String,我们肯定知道它包含一个数字。无论如何,没有本地方法可以使用原始int从String中提取数字并将其转换为数字。但是,我们可以使用包装类。
public static void main(String[] args) {
String s = "1166628";
Integer i = Integer.parseInt(s);
System.out.println(i);
}
输出:
1166628
我们成功地从String中提取了一个数字并将其分配给Integer引用变量i。顺便说一句,关于参考。您已经知道参数以不同的方式传递给方法:按值传递原语和按引用传递对象。您可以在创建自己的方法时使用这些知识:例如,如果您的方法使用小数但您需要通过引用传递逻辑,则可以将Double / Float参数传递给该方法,而不是double / float。除了包装类的方法,它们的静态字段也可以很方便。例如,假设您有以下任务:显示最大可能int值,后跟最小可能值。这个问题看起来很基本。但如果没有谷歌,你不太可能做到这一点。但是包装器可以让你轻松处理这样的“平凡任务”:
public class Main {
public static void main(String[] args) {
System.out.println(Integer.MAX_VALUE);
System.out.println(Integer.MIN_VALUE);
}
}
这些领域使您不会因为完成更严肃的任务而分心。更不用说输入2147483647 (恰好是 MAX_VALUE 的值)这一事实绝非易事!:) 此外,在上一课中,我们指出包装器对象是不可变的。
public static void main(String[] args) {
Integer a = new Integer(0);
Integer b = new Integer(0);
b = a;
a = 1;
System.out.println(b);
}
输出:
0
a 最初指向的对象的状态没有改变(因为b的值也会改变)。与String一样,不是更改包装器对象的状态,而是在内存中创建一个全新的对象。 那么,为什么 Java 的创建者最终决定在语言中保留原始类型呢?既然一切都应该是一个对象,并且我们有包装器类可以表达原语所表达的一切,为什么不只保留语言中的包装器并删除原语呢?答案很简单:性能。原始类型之所以称为原始类型,是因为它们缺少对象的许多“重量级”特性。是的,对象有很多方便的方法,但你并不总是需要它们。有时,您只需要数字 33 或 2.62 或true / false。在对象的优势无关紧要并且不需要程序运行的情况下,原语更适合该任务。
GO TO FULL VERSION