java包装类的详细介绍

前言

这是一个个人学习的博客,有错误欢迎指出,转载请注明出处,小青龙

java是面向对象的语言,那么其最小的程序单元应该是类,并且我们的类全部都是继承的Object类,所以很多工具方法参数都是Object。那么当我们需要对基本类型进行对应操作的时候,就会非常不方便,首先,基本类型的变量没有方法,不能赋值为null,再者,不符合面向对象设计原则。于是包装类的出现解决了这些问题。

1.8种基本类型的对应包装类

除了int和char两种基本类型的对应包装类的写法有些特殊外,其他基本类型的包装类就是基本类型的首字母大写

基本类型 包装类
byte Byte
short Short
char Character
int Integer
long Long
float Float
double Double
boolean Boolean

2.已过时的写法(了解)

在JDK5前想要将基本类型变量转换为对应包装类的实例或将包装类的实例转换为基本类型都会很麻烦,(我之所以还是把这种写法讲了一下,是为了防止以后看见一些比较老的程序使用这种写法,会有一些人不认识)如下:
在这里插入图片描述

2.1 基本类型变量->对应包装类实例

使用对应包装类的valueOf()类方法

Integer integer = Integer.valueOf(5);

2.2 包装类实例->对应基本类型变量

使用包装类的实例方法xxxValue()

int a = integer.intValue();//integer是一个Integer类的实例

3.现在的写法

既然都说了JDK5提供了自动装箱和自动拆箱的功能,我们就不必再使用上面的方法了

3.1 自动装箱(Autoboxing)

自动装箱指的是,我们可以直接将基本类型的值赋值给对应包装类类型的变量,系统会自动将基本类型的值包装为包装类

Integer integer = 5;

3.2 自动拆箱(AutoUnboxing)

自动拆箱指的是,我们可以将包装类对象直接赋值给对应基本类型的变量,系统会自动将包装类value赋值给基本类型的变量

int a = integer;//integer是Integer类的一个实例

补充

自动拆箱和自动装箱都只能转换为对应类型,比如Integer类的实例对象只能转换为int的变量,Boolean类的实例对象只能转换为boolean的变量.
我们之所以可以写成一下形式的原因是,2转换为Integer实例对象之后,进行了向上转型,即Integer转换为Object

Object object = 2;

这里我多举几个例子
例1: 2转为Integer之后,无法转换为Double,因为二者之间没有继承关系

Double d = 2;//报错

例2: 2转换为double类型之后可以转换为Double

Double d = (double)2;

例3: d转换为double类型之后,无法赋值给int类型,因为无法自动转型,会有截断(数据丢失)

Double d = (double)2;
int i = d;//报错

例3: 这种写法不能解决上面的错误,因为编译器认为(int)d是将Double类型的变量转换为int,所以会报错

Double d = (double)2;
int i = (int)d;//报错

例4: 正确

Boolean bo = true;

重点:基本类型中,数值型(整型\实型\字符型)不能与布尔型进行转换,在这里也是,不要试图强制转换

4.借助包装类实现基本类型和字符串类型的转换

可以通过包装类提供的方法将字符串转变为基本类型
在这里插入图片描述

4.1 基本类型->字符串类型

方法一: 将基本类型转换为字符串类型,需要使用String提供的类方法valueOf(),该方法有多个重载方法,只需要将基本类型作为参数传入即可

	String string;
	
	string = String.valueOf(true);//布尔
	
	string = String.valueOf((byte)1);//byte
	
	string = String.valueOf((short)257);//short
	
	string = String.valueOf(1);//int
	
	string = String.valueOf(1000000000000L);//long

	string = String.valueOf(1.9f);//float

	string = String.valueOf(1.9);//double

	string = String.valueOf('y');//char

方法二: 我们知道字符串连接符,我们直接用基本类型+""就可以做转换了,这里我简单演示一下

	System.out.println(2+"");

4.2 字符串类型->基本类型

使用对应包装类的parseXXX(String)类方法,注意:char类型没有没有该方法(注意:Character没有提供该方法)

	String string;
	string = "true";
	boolean temp = Boolean.parseBoolean(string);

	string = "1";
	byte temp1 = Byte.parseByte(string);

	string = "257";
	short temp2 = Short.parseShort(string);

	string = "2";
	int temp3 = Integer.parseInt(string);

	string = "1000000000000";
	long temp4 = Long.parseLong(string);

	string = "1.9f";
	Float temp5 = Float.parseFloat(string);

	string = "1.9";
	Double temp6 = Double.parseDouble(string);

5.包装类作比较

5.1 两个包装类的实例进行><>=<=比较

这里比较的是值,这里我举一个例子

public class StudyTest  {

public static void main(String[] args) {
	Integer integer = 3;
	Integer integer2 = 5;
	System.out.println(integer.hashCode());
	System.out.println(integer2.hashCode());
	System.out.println(integer>integer2);
	}
}

可以进行反编译查看,实际上比较的时候调用了Integer.inValue()方法进行了转换,转换为了int基本类型之后再进行的比较;此外,我们还可以看出我们的自动装箱实际上也调用了Integer.valueOf()方法
在这里插入图片描述

5.2 两个包装类的实例进行==比较

不同于上面的比较,这里的比较比较的是两个对象是否为同一个对象,只有为同一个对象时,才返回true(我下面举得的这个例子其实不怎么好,但是我懒得改了,所以就直接用了,应该选择两个值较大的,为什么,可以在补充中得到)

public class StudyTest  {

	public static void main(String[] args) {
		Integer integer = 3;
		Integer integer2 = 5;
		System.out.println(integer.hashCode());
		System.out.println(integer2.hashCode());
		System.out.println(integer==integer2);
	}
}

同样,我们进行反编译,可以看见明显的区别,就是没有调用Integer.intValue()方法
在这里插入图片描述

5.3 对包装类==的补充

可能有同学已经试过了,比如以下代码,会输出true,分明是两个对象,为什么会输出true呢?

public class StudyTest  {

	public static void main(String[] args) {
		Integer integer = 3;
		Integer integer2 = 3;
		System.out.println(integer.hashCode());
		System.out.println(integer2.hashCode());
		System.out.println(integer==integer2);//输出true
	}
}

解释: 我们知道自动装箱调用了Integer.valueOf()方法,那么我们进入该方法找中观察,可以看出,他对我们的值进行了比较,如果值在[IntegerCache.low,IntegerCache.high]内的话,会返回IntegerCache.cash[i+(-IntegerCache.low)]。意思就是,当你不在这个取值范围的时候,我们才会返回一个新的对象,而值在取值范围内的话,我们就返回缓冲数组中的对象
在这里插入图片描述
那我们再看看我们的IntegerCache的定义,可以看出取值范围在[-128,127],那么只要在这个范围内,创建的对象就是相同的,超过这个范围就不是同一个对象了
在这里插入图片描述
这里我们进行尝试,我们使用128,已经超过了我们的127,可以看出返回的是false
在这里插入图片描述
同样的,不仅仅是Integer有缓冲,其他的包装类也有,但不是所有包装类都有,我们的Double和Float两个包装类没有,如下
在这里插入图片描述
在这里插入图片描述
其余包装类都有,如下
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
说明:这是一个很好的设计模式,大家不要因为复杂就否认它

5.4 包装类对象和基本类型进行比较

进行的也是数值的比较,比如以下代码

public class StudyTest  {

public static void main(String[] args) {
	Integer integer = 3;
	int integer2 = 5;
	System.out.println(integer>integer2);//输出false
}
}

反编译可以看见,调用了Integer.intvalue(),进行了基本类型的转换,所以比较的是值
在这里插入图片描述

6.包装类的一些方法

除了上面说的方法,包装类还有其他优秀的方法(这里说的一些方法不是所有包装类都拥有的,请注意这一点),一些方法可能不会用到,或者说比较简单,我就不举例说明

6.1 compare(xxx val1,xxx val2)

jdk7之后,所有包装类都提供了这个类方法,用于比较基本类型的值。当然,布尔类型比较的只有四种情况,你只需要知道true>false就行,这里我就测试一下Boolean,其他的,读者自己试试
在这里插入图片描述

6.2 static String toUnsignedString(int/long i)

JDK8才有的方法,将指定的int型或long型正数转换为无符号整数对应的字符串(Integer和Long才有的方法)

6.3 static String toUnsignedString(int/long i,int radix)

JDK8才有的方法,将指定的int型或long型正数转换为指定radix进制的无符号整数对应的字符串(Integer和Long才有的方法)
在这里插入图片描述

6.4 static xxx parseUnsignedXxx(String s)

JDK8才有的方法,该方法将指定的字符串解析为无符号整数(Integer和Long才有的方法)

6.5 static xxx parseUnsignedXxx(String s,int radix)

JDK8才有的方法,该方法将指定的字符串解析为指定radix进制的无符号整数(Integer和Long才有的方法)

6.6 static int compareUnsigned(xxx x,xxx y)

JDK8才有的方法,该方法将x和y转换为无符号整数之后比较大小(Integer和Long才有的方法)

6.7 static xxx dividedUnsigned(xxx dividend,xxx divisor)

JDK8才有的方法,将dividend和divisor转换为无符号整数之后做商并返回(Integer和Long才有的方法)

System.out.println(Integer.divideUnsigned(20, 3));//输出6

6.8 static xxx remainderUnsigned(xxx dividend,xxx divisor)

JDK8才有的方法,将dividend和divisor转换为无符号整数之后做商得到余数,返回余数(Integer和Long才有的方法)

System.out.println(Integer.remainderUnsigned(20, 3));//输出2

6.9 static int toUnsignedInt(xxx x)

JDK8才有的方法,将byte或short转换为无符号int(Byte和Short才有的方法)

6.10 static long toUnsignedlong(xxx x)

JDK8才有的方法,将byte或short转换为无符号long(Byte和Short才有的方法)

7. 包装类的hashCode方法

Integer\Byte\Short\Long返回就是其对应的基本类型的值
Character返回的对应基本类型的ASCII码
剩下三个比较奇怪,我也不想看
在这里插入图片描述

8.包装类的equals方法

所有包装类都重写了equals方法,他们比较的依据都是值是否相等
在这里插入图片描述

9.包装类的toString方法

所有包装类都重写了toString方法,返回的都是值
在这里插入图片描述

结语

包装类还有很多方法,新版本的JDK拥有更多方法,建议读者阅读开发者文档
好好学习,天天向上,如有错误,欢迎指出;如有问题,评论下方,我会回复
转载请注明出处,小青龙

猜你喜欢

转载自blog.csdn.net/qq_44809362/article/details/106359752