Java:包装类型(2021.5.2)
Java数据类型分为两种:
基本类型:byte、short、int、long、boolean、float、double、char
引用类型:所有的class和interface
引用类型可以赋值为null,但是基本类型不能赋值为null。
Java是面向对象编程,所有基本类型都有与之对应的引用类型,比如Integer之于int,Interger类就是int的包装类(Wrapper Class)。
基本类型对应的引用类型
基本类型 |
对应的引用类型(均为java.lang下的) |
boolean | Boolean |
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
可以看到,这些引用类型就是基本类型首字母大写以后的结果(除了char和Character)。
转换方法
1、基本类型——>引用类型:int——>Integer
①、new这个引用类型的实例;
②、直接赋值给该引用类型;
Integer n1 = new Integer (100)
Integer n1 = 100;
③、引用类型的valueOf(var)方法(静态方法/类方法)
从任意可以转化数据转化而来,可以是该引用类型的基本类型或String:
Integer n2 = Integer.valueOf("100");
2、引用类型→基本类型:Integer→int
①、各种类型的xxxValue()方法(对象方法,需要用实例调用)
Number num = new Integer(999); byte b = num.byteValue(); int n = num.intValue(); long ln = num.longValue(); float f = num.floatValue(); double d = num.doubleValue();
②、直接赋值
Integer n = 100; int x = n;
③先转为String,再转为基本类型 Integer.parseInt()
int n = Integer.parseInt("100");
3、引用类型→另一种引用类型:先通过toString转化为字符串,再从字符串转化
Double→Long
Long l = Long.valueOf(d.toString());//假设d为某Double类型
Auto Boxing
看之前两种类型的相互转化,我们发现可以通过直接赋值的方式进行双向转化。
Java编译器可以帮我们自动在int和Integer之间转型,因此我们可以用直接赋值的方式在两种类型之间转化。
这种通过直接赋值的写法把int转化为Integer的方法,称为自动装箱(Auto Boxing);反过来,把Integer转化为int的方法,称为自动拆箱(Auto Unboxing)。
注意:自动装箱和自动拆箱发生在编译阶段,所以我们不用去关心它是如何实现的,其目的是为了少写代码。
装箱和拆箱会影响代码执行效率,因为编译后的class代码是严格区分基本类型和引用类型的,并且自动拆箱时可能会报NullPointerException错误,这是由于引用类型在初始化时可能会初始化为null,而基本类型是不能赋值为null的,此时直接赋值就会报错。
不变类
所有的包装类型都是不变类(用final修饰),我们看Integer的源码可知,它的核心代码如下:
public final class Integer{ private final int value; }
因此,一旦创建了Integer对象,该对象就是不变的。
两个包装类比较大小
对两个Integer的比较,不能用==,而应该像String一样,使用equals()比较。
静态工厂
之前我们曾说过,在我们自己创建Integer的时候,有3种方法:
Integer n = new Integer (100);//① Integer n = Integer.valueOf(100);//② Integer n = 100; //③
其中方法③和方法②本质上是一致的,这两者都比方法①要好。
原因:方法①总是创建新的Integer实例;方法②把内部优化留给Integer的实现者去做,即使当前版本没有优化,也可能在下一个版本进行优化。
静态工厂方法:我们把能创建“新”对象的静态方法称为静态工厂方法,Integer.valueOf()就是静态工厂方法,它尽可能地返回缓存的实例以节省内存。
创建新对象时,优先选择静态工厂方法而非new操作符。
进制转换
Integer类本身还提供了大量方法,例如:最常用的静态方法parseInt()可以把String解析为一个整数,还可以指定具体的转化进制(通过第二个参数):
int n1 = Integer.parseInt("100");//十进制 int n2 = Integer.parseInt("100",16);//十六进制
Integer还可以把整数格式转化为指定进制的字符串:
Integer.toString(100);//"100",10进制 Integer.toString(100,36);//"2s",36进制 Integer.toHexString(100);//16进制 Integer.toOctalString(100);//8进制 Integer.toBinaryString(100);//2进制
我们经常使用的System.out.println(n);是依靠核心库自动把整数格式化为10进制并输出显示在屏幕上,使用Integer.toHexString(n)则通过核心库自动把整数化为16进制。
这里我们注意到程序设计的一个重要原则:数据的存储和显示要分离。
一些包装类中有用的静态变量
//boolean只有两个值true/false,其包装类型只需要引用Boolean提供的静态字段: Boolean t = Boolean.TRUE; Boolean f = Boolean.FALSE; //整型最大/最小值 int max = Integer.MAX_VALUE;//2147483647 int min = Integer.MIN_VALUE;//-2147483648 //类型占用的bit和byte数量 int sizeOfLong = Long.SIZE;//64bits int bytesOfLong = Long.BYTES;//8 bytes
最后,就像我们之前所学的多态的知识,我们可以利用这些引用类型的父类来接收这些引用类型。所有整数和浮点数的包装类型都继承自Number:
// 向上转型为Number: Number num = new Integer(999); // 获取byte, int, long, float, double: byte b = num.byteValue(); int n = num.intValue(); long ln = num.longValue(); float f = num.floatValue(); double d = num.doubleValue();
无符号整型
在Java中,并没有无符号整型的基本数据类型。无符号整型→有符号整型的转换在Java中需要借助包装类型的静态方法来实现。
例如,byte是有符号整型,范围是-128~127,但是如果把byte看做无符号整型,它的范围就是0~255,那么我们如何把一个负的byte按转换为正的无符号整型:
方法:Byte.toUnsignedInt(n),n是有符号的byte
public class Main { public static void main(String[] args) { byte x = -1; byte y =127; System.out.println(Byte.toUnsignedInt(x)); System.out.println(Byte.toUnsignedInt(y)); } }
因此,可以运用各引用类型的XXX.toUnsignedInt(n)方法,可以把各个类型的有符号整型数转化为无符号类型。
总结
- 基本类型→引用类型:
Integer n = new Integer (100);//① Integer n = Integer.valueOf(100);//② Integer n = 100; //③
②与③方法最好,①总是会额外创建Interger实例;
- 引用类型→基本类型:
//①各种类型的xxxValue()方法 Number num = new Integer(999); byte b = num.byteValue(); int n = num.intValue(); long ln = num.longValue(); float f = num.floatValue(); double d = num.doubleValue(); //②直接赋值 Integer n = 100; int x = n;
//③先转为String,再转为基本类型 Integer.parseInt()
int n = Integer.parseInt("100"); - 可以用直接赋值的方式在引用类型和基本类型间转化,JVM可以自行转型。这种方式称为自动装箱与自动拆箱。
- 对两个引用类的比较,用equals方法。
- 进制转换:Integer.parseInt("xxx",HEX):把xxx对应的整数String转化为HEX指定进制的整数(int类型);Integer.toXxxString(int n):将整数n转化为字符串形式的String
toString(num,hex=10) 把整数num转为String类型,用hex进制(默认10进制) toHexString(num) 16进制转String类型 toOctalString(num) 8进制 toBonaryString(num) 2进制 - 多态——用Number类型对象接收所有引用类型对象:
Number num = new Integer(999);
- Java并没有无符号整型。无符号整型<——>有符号整型在Java中,通过各个引用类型的XXX.toUnsignedInt(n)方法,n是byte类型。不过最常用的是Byte类型,因为Byte本身就是-128~127的有符号整型,转化前后,刚好与8bit的有/无符号整型相互对应。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性