type
status
date
slug
summary
tags
category
icon
password
Property
Java的数据类型分两种:
- 基本类型:
byte
,short
,int
,long
,boolean
,float
,double
,char
- 引用类型:所有
class
和interface
类型
引用类型可以赋值为
null
,表示空,但基本类型不能赋值为null
:如何把一个基本类型视为对象(引用类型)?
比如,想要把
int
基本类型变成一个引用类型,可以定义一个Integer
类,它只包含一个实例字段int
,这样,Integer
类就可以视为int
的包装类(Wrapper Class):定义好了
Integer
类,就可以把int
和Integer
互相转换:因为包装类型非常有用,Java核心库为每种基本类型都提供了对应的包装类型:
Auto Boxing
因为
int
和Integer
可以互相转换,所以Java编译器可以帮助我们自动在int
和Integer
之间转型:这种直接把
int
变为Integer
的赋值写法,称为自动装箱(Auto Boxing);反过来,把Integer
变为int
的赋值写法,称为自动拆箱(Auto Unboxing)。自动装箱和自动拆箱只发生在编译阶段,目的是为了少写代码。装箱和拆箱会影响代码的执行效率,因为编译后的
class
代码是严格区分基本类型和引用类型的。并且,自动拆箱执行时可能会报NullPointerException
:不变类
所有的包装类型都是不变类。查看
Integer
的源码可知,它的核心代码如下:因此,一旦创建了
Integer
对象,该对象就是不变的。对两个
Integer
实例进行比较要特别注意:绝对不能用==
比较,因为Integer
是引用类型,必须使用equals()
比较:==
比较,较小的两个相同的Integer
返回true
,较大的两个相同的Integer
返回false
,这是因为Integer
是不变类,编译器把Integer x = 127;
自动变为Integer x = Integer.valueOf(127);
,为了节省内存,Integer.valueOf()
对于较小的数,始终返回相同的实例,因此,==
比较“恰好”为true
,但绝不能因为Java标准库的Integer
内部有缓存优化就用==
比较,必须用equals()
方法比较两个Integer
因为
Integer.valueOf()
可能始终返回同一个Integer
实例,因此,在创建Integer
的时候,以下两种方法:- 方法1:
Integer n = new Integer(100);
- 方法2:
Integer n = Integer.valueOf(100);
方法2更好,因为方法1总是创建新的
Integer
实例,方法2把内部优化留给Integer
的实现者去做,即使在当前版本没有优化,也有可能在下一个版本进行优化。我们把能创建“新”对象的静态方法称为静态工厂方法。
Integer.valueOf()
就是静态工厂方法,它尽可能地返回缓存的实例以节省内存。如果考察
Byte.valueOf()
方法的源码,可以看到,标准库返回的Byte
实例全部是缓存实例,但调用者并不关心静态工厂方法以何种方式创建新实例还是直接返回缓存的实例。进制转换
Integer
类本身还提供了大量方法,例如,最常用的静态方法parseInt()
可以把字符串解析成一个整数:Integer
还可以把整数格式化为指定进制的字符串:上述方法的输出都是
String
,在计算机内存中,只用二进制表示,不存在十进制或十六进制的表示方法。int n = 100
在内存中总是以4字节的二进制表示:System.out.println(n);
是依靠核心库自动把整数格式化为10进制输出并显示在屏幕上;使用Integer.toHexString(n)
则通过核心库自动把整数格式化为16进制。程序设计的一个重要原则:数据的存储和显示要分离。
Java的包装类型还定义了一些有用的静态变量
所有的整数和浮点数的包装类型都继承自
Number
,因此,可以非常方便地直接通过包装类型获取各种基本类型:处理无符号整型
C语言则提供了CPU支持的全部数据类型,包括无符号整型。Java并没有无符号整型(Unsigned)的基本数据类型,
byte
、short
、int
和long
都是带符号整型,最高位是符号位。无符号整型和有符号整型的转换在Java中就需要借助包装类型的静态方法完成。byte是有符号整型,范围是
-128
~+127
,但如果把byte
看作无符号整型,它的范围就是0
~255
。把一个负的
byte
按无符号整型转换为int
:类似的,可以把一个
short
按unsigned转换为int
,把一个int
按unsigned转换为long
。