java包装类
Wrapper Classes(包装类)
装箱和拆箱
-
装箱(auto boxing):基本数据类型转换为包装类的过程(在编译器执行),例如把 int 包装成 Integer 类的对象
Integer obj = m;
<==>Integer obj=Integer.valueOf(m);
<==>Integer obj = new Integer(x);
/**
* 1、JDK 1.5 老特性 自动装箱 ( auto-boxing )
* 所谓自动装箱,就是将 基本类型 的数值 "自动包装" 到一个 包装类类型的实例中
* 2、将 基本类型的值 赋值给 包装类类型的 引用变量 时,就会发生 自动装箱 ( auto-boxing )
*/ -
拆箱(auto unboxing):包装类变为基本数据类型的过程(在编译器执行),例如把 Integer 类的对象重新简化为 int
int n = obj;
<==>int y = obj.intValue();
/**
* 1、JDK 1.5 老特性 自动拆箱 ( auto-unboxing )
* 所谓自动拆箱,就是将 包装类类型的实例中所封装的 基本类型的值 取出来,仍然以基本类型数值的方式来运算
* 2、当将一个包装类类型的引用变量的值 "赋值" 给一个基本数据类型的变量时,会发生 自动拆箱
* 3、用一个包装类类型的引用变量 参与 运算时,会发生自动拆箱
*/public class Demo {
public static void main(String[] args) {
int m = 500;
Integer obj = m; // 自动装箱
int n = obj; // 自动拆箱
int x = 500;
Integer obj = new Integer(x); // 手动装箱
int y = obj.intValue(); // 手动拆箱
Integer obj1 = 500;
System.out.println("obj等价于obj1返回结果为" + obj.equals(obj1));
}
}
IntegerCache 内部类
-
在范围内赋值地址相同,范围外赋值地址不同
-
如果是该范围内的数字就直接从 缓存数组中获取已经创建好的 Integer 实例 ,否则就创建新的 Integer 实例
/**
* 1、所谓的自动装箱,实际上就是由编译器将 相应的代码替换为 Xxx.valueOf( xxx value )
* 2、让一个 包装类类型的变量 与 基本类型的变量比较时,会发生自动拆箱
* 3、Integer.valueOf( int ) 方法中会判断 参数对应的数字是否是 [ -128 , 127 ] 之间
* 4、了解:
* 在 Ineger 类内部有一个 IntegerCache 内部类,
* 在 IntegerCache 中有一个 cache 数组,其中默认缓存了 [ -128 , 127 ] 之间 的数字对应的 Integer 实例
* 5、自行测试 其它的 包装类中的 缓存
*/
public class IntegerCacheTest {
public static void main(String[] args) {
int x = 100 ; // 基本类型
Integer a = 100 ; // 引用类型 ( auto-boxing : Integer.valueOf( 100 ) )
Integer b = 100 ; // 引用类型 ( auto-boxing : Integer.valueOf( 100 ) )
// 但凡是使用 == 比较两个变量,一定是比较变量中存储的值
System.out.println( a == b ); // true : 说明两者存储的地址是【相同】的
System.out.println( "a : " + Integer.toHexString( System.identityHashCode( a ) ) );
System.out.println( "b : " + Integer.toHexString( System.identityHashCode( b ) ) );
System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );
// 自动拆箱 ( auto-unboxing ) : 手动拆箱后的代码是 a.intValue() == x
System.out.println( a == x ); // true : 说明包装类类型的实例中封装的数值 与 基本类型变量中存储的数值 是相等的
System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );
// Object o = 100 ; // auto-boxing
// System.out.println( o == x ); // 错误: 二元运算符 '==' 的操作数类型错误
Integer u = 1000 ; // Integer.valueOf( 1000 )
// Integer.valueOf( int ) 方法中会判断 参数对应的数字是否是 [ -128 , 127 ] 之间,
// 如果是该范围内的数字就直接从 缓存数组中获取已经创建好的 Integer 实例 ,否则就创建新的 Integer 实例
Integer w = 1000 ; // Integer.valueOf( 1000 )
System.out.println( u == w ); // false : 说明两者存储的地址是【不相同】的
System.out.println( "u : " + Integer.toHexString( System.identityHashCode( u ) ) );
System.out.println( "w : " + Integer.toHexString( System.identityHashCode( w ) ) );
System.out.println( u.equals( w ) ); // 比较两个 Integer 实例中封装的 数值 是否相等
}
}
不可变模式
/**
* 1、被 final 修饰的类就是所谓的 【最终类】 ( 或者称作 不可变类 / 不变类 )
* 2、被 final 修饰的类是没有子类的
* 3、被 final 修饰的变量被称作 【最终变量】 ( 可以是 类变量、实例变量 、局部变量 、参数 )
*/
public final class Decimal {
// 被 final 修饰的 类变量 被称作【常量】
public final static long MAX_VALUE = 0x7fffffffffffffffL ;
// 常量名称中所有单词一律大写,多个单词之间使用 下划线 隔开
public final static long MIN_VALUE = 0x8000000000000000L ;
// 被 final 修饰的 实例变量 在初始化之后不能再次赋值
private final long value ;
{
// System.out.println( "this.value : " + this.value ); // 错误: 可能尚未初始化变量value
}
public Decimal ( long value ) {
// System.out.println( "this.value : " + this.value ); // 错误: 可能尚未初始化变量value
this.value = value ;
System.out.println( "this.value : " + this.value );
}
public long getValue(){
return this.value ;
}
public void setValue( long value ) {
// this.value = value ; // 错误: 无法为最终变量value分配值
}
public static Decimal valueOf( long value ) {
return new Decimal( value );
}
public static void main(String[] args) {
// 在 堆内存中所创建的 Decimal 对象是不可变的 ( 因为其内部 实例变量的 值不可更改 ) 【不可变对象】
Decimal d = new Decimal( 100L );
System.out.println( d.getValue() );
System.out.println( System.identityHashCode( d ) );
System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );
// 但是 Decimal 类型的变量 d 的值 是可以改变的,也就是 d 可以引用不同的 Decimal 实例
d = new Decimal( 200L );
System.out.println( d.getValue() );
System.out.println( System.identityHashCode( d ) );
System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );
d = Decimal.valueOf( 300L );
System.out.println( d.getValue() );
System.out.println( System.identityHashCode( d ) );
}
}
被final修饰的值不能再改变,可以包装成一个类,就可以多次实例化,每次实例化的值可以不同,但是实例化之后的值不能改变。所以有getter但是没有setter
基本数据类型包装成类
1、八种基本数据类型对应的包装类类型
-
byte —–> Byte
-
short —-> Short
-
int ——> Integer
-
long —–> Long
-
float —-> Float
-
double –> Double
-
boolean –> Boolean
-
char —–> Character
2、八种基本类型对应的包装类都有一个将相应的基本类型数据封装成该类对象的 valueOf 方法
public static Xxx valueOf( xxx value ){}
/**
* 获得 某种 基本数据类型 数值 对应的 包装类类型的实例
* 在 Java 9 之前使用 包装类的 构造方法创建实例
* 从 Java 9 开始使用 valueOf 等方法来获取 实例
*/
public class WrapperTest1 {
public static void main(String[] args) {
// Java 9 之前使用 构造方法创建 相应的实例
byte b = 100 ;
Byte first = new Byte( b); // 但是从 Java 9 开始 包装类的 构造方法均已废弃
System.out.println( first ); // first.toString()
short s = 9527 ;
Short second = new Short( s ); // 但是从 Java 9 开始 包装类的 构造方法均已废弃
System.out.println( second ); // second.toString()
// 从 Java 9 开始 建议使用 工厂方法来创建 包装类的实例
Integer third = Integer.valueOf( 999 ) ; // 将 int 类型的数值 封装到一个 Integer 实例中
System.out.println( third ); // third.toString()
Long fourth = Long.valueOf( 999L ) ; // 将 long 类型的数值 封装到一个 Long 实例中
System.out.println( fourth ); // fourth.toString()
System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );
System.out.println( fourth.getClass() ); // 获得运行时类型
System.out.println( fourth.hashCode() ); // 获得哈希码值
System.out.println( fourth.toString() ); // 获取字符串表示形式
// 即使变量 fourth 指向的 对象对应的类 重写 hashCode 方法,
// 我们仍然可以通过 identityHashCode 来获取 由 Object 提供的 hashCode 方法所返回的值
System.out.println( System.identityHashCode( fourth ) );
}
}
public class WrapperTest2 {
public static void main(String[] args) {
// valueOf 接受一个与之对应的基本数据类型的数值做参数,返回一个当前类型的对象
Byte b = Byte.valueOf( (byte) 100 ); // byte ---> Byte
System.out.println( b + " , " + b.getClass().getName() );
Short s = Short.valueOf( (short)1000 ); // short ---> Short
System.out.println( s + " , " + s.getClass().getName() );
Integer i = Integer.valueOf( 9527 ); // int ---> Integer
System.out.println( i + " , " + i.getClass().getName() );
Long o = Long.valueOf( 123456789L ); // long ---> Long
System.out.println( o + " , " + o.getClass().getName() );
Float f = Float.valueOf( 123.456789F ); // float --> Float
System.out.println( f + " , " + f.getClass().getName() );
Double d = Double.valueOf( 3.14 ); // double ---> Double
System.out.println( d + " , " + d.getClass().getName() );
Boolean z = Boolean.valueOf( true ); // boolean ---> Boolean
System.out.println( z + " , " + z.getClass().getName() );
Character c = Character.valueOf( '汉' ); // char ----> Character
System.out.println( c + " , " + c.getClass().getName() );
}
}
Integer 类
方法 | 返回值 | 功能 |
---|---|---|
byteValue() | byte | 以 byte 类型返回该 Integer 的值 |
shortValue() | short | 以 short 类型返回该 Integer 的值 |
intValue() | int | 以 int 类型返回该 Integer 的值 |
toString() | String | 返回一个表示该 Integer 值的 String 对象 |
equals(Object obj) | boolean | 比较此对象与指定对象是否相等 |
compareTo(Integer anotherlnteger) | int | 在数字上比较两个 Integer 对象,如相等,则返回 0; 如调用对象的数值小于 anotherlnteger 的数值,则返回负值; 如调用对象的数值大于 anotherlnteger 的数值,则返回正值 |
valueOf(String s) | Integer | 返回保存指定的 String 值的 Integer 对象 |
parseInt(String s) | int | 将数字字符串转换为 int 数值 |
Integer 类包含以下 4 个常量。
-
MAX_VALUE:值为 231-1 的常量,它表示 int 类型能够表示的最大值。
-
MIN_VALUE:值为 -231 的常量,它表示 int 类型能够表示的最小值。
-
SIZE:用来以二进制补码形式表示 int 值的比特位数。
-
TYPE:表示基本类型 int 的 Class 实例。
下面的代码演示了 Integer 类中常量的使用。
纯文本复制
int max_value = Integer.MAX_VALUE; // 获取 int 类型可取的最大值
int min_value = Integer.MIN_VALUE; // 获取 int 类型可取的最小值
int size = Integer.SIZE; // 获取 int 类型的二进制位
Class c = Integer.TYPE; // 获取基本类型 int 的 Class 实例
Float 类
方法 | 返回值 | 功能 |
---|---|---|
byteValue() | byte | 以 byte 类型返回该 Float 的值 |
doubleValue() | double | 以 double 类型返回该 Float 的值 |
floatValue() | float | 以 float 类型返回该 Float 的值 |
intValue() | int | 以 int 类型返回该 Float 的值(强制转换为 int 类型) |
longValue() | long | 以 long 类型返回该 Float 的值(强制转换为 long 类型) |
shortValue() | short | 以 short 类型返回该 Float 的值(强制转换为 short 类型) |
isNaN() | boolean | 如果此 Float 值是一个非数字值,则返回 true,否则返回 false |
isNaN(float v) | boolean | 如果指定的参数是一个非数字值,则返回 true,否则返回 false |
toString() | String | 返回一个表示该 Float 值的 String 对象 |
valueOf(String s) | Float | 返回保存指定的 String 值的 Float 对象 |
parseFloat(String s) | float | 将数字字符串转换为 float 数值 |
在 Float 类中包含了很多常量,其中较为常用的常量如下。
-
MAX_VALUE:值为 1.4E38 的常量,它表示 float 类型能够表示的最大值。
-
MIN_VALUE:值为 3.4E-45 的常量,它表示 float 类型能够表示的最小值。
-
MAX_EXPONENT:有限 float 变量可能具有的最大指数。
-
MIN_EXPONENT:标准化 float 变量可能具有的最小指数。
-
MIN_NORMAL:保存 float 类型数值的最小标准值的常量,即 2-126。
-
NaN:保存 float 类型的非数字值的常量。
-
SIZE:用来以二进制补码形式表示 float 值的比特位数。
-
TYPE:表示基本类型 float 的 Class 实例。
下面的代码演示了 Float 类中常量的使用。
纯文本复制
float max_value = Float.MAX_VALUE; // 获取 float 类型可取的最大值
float min_value = Float.MIN_VALUE; // 获取 float 类型可取的最小值
float min_normal = Float.MIN_NORMAL; // 获取 float 类型可取的最小标准值
float size = Float.SIZE; // 获取 float 类型的二进制位
Double 类
方法 | 返回值 | 功能 |
---|---|---|
byteValue() | byte | 以 byte 类型返回该 Double 的值 |
doubleValue() | double | 以 double 类型返回该 Double 的值 |
fioatValue() | float | 以 float 类型返回该 Double 的值 |
intValue() | int | 以 int 类型返回该 Double 的值(强制转换为 int 类型) |
longValue() | long | 以 long 类型返回该 Double 的值(强制转换为 long 类型) |
shortValue() | short | 以 short 类型返回该 Double 的值(强制转换为 short 类型) |
isNaN() | boolean | 如果此 Double 值是一个非数字值,则返回 true,否则返回 false |
isNaN(double v) | boolean | 如果指定的参数是一个非数字值,则返回 true,否则返回 false |
toString() | String | 返回一个表示该 Double 值的 String 对象 |
valueOf(String s) | Double | 返回保存指定的 String 值的 Double 对象 |
parseDouble(String s) | double | 将数字字符串转换为 Double 数值 |
在 Double 类中包含了很多常量,其中较为常用的常量如下。
-
MAX_VALUE:值为 1.8E308 的常量,它表示 double 类型的最大正有限值的常量。
-
MIN_VALUE:值为 4.9E-324 的常量,它表示 double 类型数据能够保持的最小正非零值的常量。
-
NaN:保存 double 类型的非数字值的常量。
-
NEGATIVE_INFINITY:保持 double 类型的负无穷大的常量。
-
POSITIVE_INFINITY:保持 double 类型的正无穷大的常量。
-
SIZE:用秦以二进制补码形式表示 double 值的比特位数。
-
TYPE:表示基本类型 double 的 Class 实例。
Number类
Number 是一个抽象类,也是一个超类(即父类)。Number 类属于 java.lang 包,所有的包装类(如 Double、Float、Byte、Short、Integer 以及 Long)都是抽象类 Number 的子类。
方法 | 说明 |
---|---|
byte byteValue(); | 返回 byte 类型的值 |
double doubleValue(); | 返回 double 类型的值 |
float floatValue(); | 返回 float 类型的值 |
int intValue(); | 返回 int 类型的值 |
long longValue(); | 返回 long 类型的值 |
short shortValue(); | 返回 short 类型的值 |
Character
方法 | 描述 |
---|---|
void Character(char value) | 构造一个新分配的 Character 对象,用以表示指定的 char 值 |
char charValue() | 返回此 Character 对象的值,此对象表示基本 char 值 |
int compareTo(Character anotherCharacter) | 根据数字比较两个 Character 对象 |
boolean equals(Character anotherCharacter) | 将此对象与指定对象比较,当且仅当参数不是 null,而 是一个与此对象 包含相同 char 值的 Character 对象时, 结果才是 true |
boolean isDigit(char ch) | 确定指定字符是否为数字,如果通过 Character. getType(ch) 提供的字 符的常规类别类型为 DECIMAL_DIGIT_NUMBER,则字符为数字 |
boolean isLetter(int codePoint) | 确定指定字符(Unicode 代码点)是否为字母 |
boolean isLetterOrDigit(int codePoint) | 确定指定字符(Unicode 代码点)是否为字母或数字 |
boolean isLowerCase(char ch) | 确定指定字符是否为小写字母 |
boolean isUpperCase(char ch) | 确定指定字符是否为大写字母 |
char toLowerCase(char ch) | 使用来自 UnicodeData 文件的大小写映射信息将字符参数转换为小写 |
char toUpperCase(char ch) | 使用来自 UnicodeData 文件的大小写映射信息将字符参数转换为大写 |
Boolean类
方法 | 返回值 | 功能 |
---|---|---|
booleanValue() | boolean | 将 Boolean 对象的值以对应的 boolean 值返回 |
equals(Object obj) | boolean | 判断调用该方法的对象与 obj 是否相等。当且仅当参数不是 null,且与调用该 方法的对象一样都表示同一个 boolean 值的 Boolean 对象时,才返回 true |
parseBoolean(String s) | boolean | 将字符串参数解析为 boolean 值 |
toString() | string | 返回表示该 boolean 值的 String 对象 |
valueOf(String s) | boolean | 返回一个用指定的字符串表示的 boolean 值 |
在 Boolean 类中包含了很多的常量,其中较为常用的常量如下。
-
TRUE:对应基值 true 的 Boolean 对象。
-
FALSE:对应基值 false 的 Boolean 对象。
-
TYPE:表示基本类型 boolean 的 Class 对象。
Byte 类
Byte 类提供了两个构造方法来创建 Byte 对象。
1. Byte(byte value)
通过这种方法创建的 Byte 对象,可以表示指定的 byte 值。例如,下面的示例将 5 作为 byte 类型变量,然后再创建 Byte 对象。
byte my_byte = 5;
Byte b = new Byte(my_byte);
2. Byte(String s)
通过这个方法创建的 Byte 对象,可表示 String 参数所指定的 byte 值。例如,下面的示例将 5 作为 String 类型变量,然后再创建 Byte 对象。
String my_byte = "5";
Byte b = new Byte(my_byte);
注意:必须使用数值型的 String 变量作为参数才能创建成功,否则会抛出 NumberFormatException 异常。
Byte 类的常用方法
在 Byte 类内部包含了一些和 Byte 操作有关的方法,见表 1。
方法 | 返回值 | 功能 |
---|---|---|
byteValue() | byte | 以一个 byte 值返回 Byte 对象 |
compareTo(Byte bytel) | int | 在数字上比较两个 Byte 对象 |
doubleValue() | double | 以一个 double 值返回此 Byte 的值 |
intValue() | int | 以一个 int 值返回此 Byte 的值 |
parseByte(String s) | byte | 将 String 型参数解析成等价的 byte 形式 |
toStringO | String | 返回表示此 byte 值的 String 对象 |
valueOf(String s) | Byte | 返回一个保持指定 String 所给出的值的 Byte 对象 |
equals(Object obj) | boolean | 将此对象与指定对象比较,如果调用该方法的对象与 obj 相等 则返回 true,否则返回 false |
Byte 类的常用常量
在 Byte 类中包含了很多的常量,其中较为常用的常量如下。
-
MIN_VALUE:byte 类可取的最小值。
-
MAX_VALUE:byte 类可取的最大值。
-
SIZE:用于以二进制补码形式表示的 byte 值的位数。
-
TYPE:表示基本类 byte 的 Class 实例。
基本数据类型和包装类的区别
-
一切皆对象,但是八大基本类型却不是对象。
-
声明方式不同,引用数据类型需要用new关键字来创建,基本数据类型不需要。
-
存储位置不同,基本数据类型直接存储保存在堆栈中,能高效存取,引用数据类型需要引用指向实例,具体的实列保存在堆中。
-
引用数据类型的初始值为null,基本数据类型的初始值依其数据类型而定。
将字符串转换为数值类型
在 Integer 和 Float 类中分别提供了以下两种方法:
① Integer 类(String 转 int 型)
int parseInt(String s);
s 为要转换的字符串。
② Float 类(String 转 float 型)
float parseFloat(String s)
注意:使用以上两种方法时,字符串中的数据必须由数字组成,否则转换时会出现程序错误。
下面为字符串转换为数值类型的例子:
public class Demo {
public static void main(String[] args) {
String str1 = "30";
String str2 = "30.3";
// 将字符串变为int型
int x = Integer.parseInt(str1);
// 将字符串变为float型
float f = Float.parseFloat(str2);
System.out.println("x = " + x + ";f = " + f);
}
}
运行结果:
x = 30;f = 30.3
将整数转换为字符串
Integer 类有一个静态的 toString() 方法,可以将整数转换为字符串。例如:
public class Demo {
public static void main(String[] args) {
int m = 500;
String s = Integer.toString(m);
System.out.println("s = " + s);
}
}
运行结果:
s = 500
包装类型的作用
包装类型是为了方便对基本数据类型进行操作,包装类型可以解决一些基本类型解决不了的问题:
-
基本数据类型之间的相互转换不是都可以制动转换的,而你强制转换又会出问题,比如String类型的转换为int类型的,那么jdk为了方便用户就提供了相应的包装类。
-
集合不允许存放基本数据类型,只能存放应用数据类型。 add(Object o)
-
基本类型可以和包装类型直接相互转换,自动装箱拆箱
-
通过包装类型的parse方法可以实现基本数据类型+String类型之间的相互转换。
-
函数需要传递进去的参数为Object类型,传入基本数据类型就不可行。
1 public void test(Object obj){
2 }
3
4 test(new Integer(5));