- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章Java--装箱和拆箱详解由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
八大基本类型都有一个与之对应的类:
基本类型 | 类 |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
boolean | Boolean |
除了后两个Character和Boolean类是Object派生类外,其余六个是继承自Number类.
这些类称为包装器(wrapper),一旦构造了对象包装器,就不允许更改包装器在其中的值同时,对象包装器类还是final修饰,所以也不能定义继承它们的子类.
有时候需要将基本类型转换为对象,比如定义一个整数型列表,尖括号中的类型参数不允许是基本类型,即不允许写成ArrayList<int>,这时就需要用到Integer包装器类,可以声明一个Integer对象的数组列表ArrayList<Integer>.
而且为了便于添加int类型的元素到ArrayList<Integer>中,下面语句会自动装箱 。
1
|
list.add(
8
);
|
即自动地变换成:
1
|
list.add(Integer.valueof(
8
));
|
再比如Integer num=8;也是自动装箱,会转换成Integer num=Integer.valueOf(8);,即将基本类型赋值给相应的类时,会触发自动装箱.
但是由于装箱操作会创建对象,频繁的装箱操作会消耗许多内存,影响性能,所以应该尽量避免装箱.
同样的,将类转换为对应的基本类型的过程就称为拆箱,如上面的Integer类型变量num,int num2=num;就会触发自动拆箱,自动地转换为int num2=num.intValue();.
还有在算术表达式中也能够自动地装箱和拆箱,例如:
1
2
3
|
Integer n=
6
;
n++;
n-=
2
;
|
编译器将自动地插入一条对象拆箱的指令,然后进行自增计算,最后再将结果装箱.
注意装箱和拆箱是编译器认可的,而不是虚拟机,编译器在生成类的字节码时,插入必要的方法调用,而虚拟机只是执行这些字节码.
使用数值对象包装器可以将某些基本方法防止在包装器中,例如parseInt()方法将一个数字字符串转换成数值,parseInt()是一个静态方法,与这里的Integer类对象没有任何关系,只是Integer类是放置这个方法的一个好地方罢了.
而我们的拆箱装箱无非是自动的调用了放置在类里面的方法如intValue()和valueOf()等.
首先看看Integer.valueOf()函数的源码,就知道==的坑了.
1
2
3
|
public
static
Integer valueOf(
int
i) {
return
i >=
128
|| i < -
128
?
new
Integer(i) : SMALL_VALUES[i +
128
];
}
|
它会首先判断 i i i的大小:如果 i > = 128 ∣ ∣ i < − 128 i>=128||i<-128 i>=128∣∣i<−128,就创建一个Integer对象,否则执行SMALL_VALUES[i + 128],再定位到SMALL_VALUES:
1
|
private
static
final
Integer[] SMALL_VALUES =
new
Integer[
256
];
|
它是一个已经创建好的静态的Integer数组对象,也就是说 i i i在 [ − 128 , 128 ) [-128,128) [−128,128)的范围内时,不会创建新的对象,否则会创建新的对象,这也就是装箱为什么创建对象,从而消耗内存.
( 插播反爬信息 )博主CSDN地址:https://wzlodq.blog.csdn.net/ 。
比如以下==判断:
1
2
3
4
5
6
7
8
|
public
static
void
main(String[] args) {
Integer i1=
88
;
Integer i2=
88
;
Integer i3=
666
;
Integer i4=
666
;
System.out.println(i1==i2);
//true
System.out.println(i3==i4);
//false
}
|
==是判断两个对象的内存地址是不是相等,显然88在区间(-128,128)内,直接指向同一个创建好的数组,而666则会重新创建新对象.
同样的boolean、byte、char<128;shot、int介于[-128,127]间时,会包装到固定的对象中,比较结果一定成立,否则会创建新的对象,比较结果不成立.
这样我们就能知道,混用时是自动拆箱还是自动装箱了,如:
1
2
3
|
Integer n=
666
;
int
m=
666
;
System.out.println(n==m);
//true
|
如果是n自动拆箱,则指向常量池同一地址,则结果为true;如果是m自动装箱,不在区间范围内,创建新对象,则结果为false。答案是n自动拆箱.
再如:
1
2
3
4
5
|
Integer x=
100
;
int
y=
200
;
Long z=300l;
System.out.println(x+y==z);
//true
System.out.println(z.equals(x+y));
//false
|
如果x、y、z自动拆箱则指向常量池同一地址,==结果true;如果x、y拆箱后装箱成Long,不在区间范围内,创建新对象,= =结果是false。答案是会拆箱.
那equals为什么输出false?因为equals除了比较值相同外,还会比较数据类型,显然两者拆箱后分别是int和long型,故判断为false.
由于包装类的引用可以为null,所以自动装箱时可能会抛出一个NullPointerException异常,如:
1
2
|
Integer n=
null
;
int
m=n;
|
另外如果在一个条件表达式中混合使用Integer和Double类型,Integer值会拆箱,提升为Double,再装箱为Double:
1
2
3
|
Integer n=
6
;
Double m=
8.0
;
System.out.println(
true
?n:m);
//6.0
|
本篇文章就到这里了,希望能给你带来帮助,也希望您能够多多关注我的更多内容.
原文链接:https://wzlodq.blog.csdn.net/article/details/117374737 。
最后此篇关于Java--装箱和拆箱详解的文章就讲到这里了,如果你想了解更多关于Java--装箱和拆箱详解的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
请告诉我哪种算法适用于以下问题: 在给定的 3 个月内,我们的项目数量有限(通常 < 50)。每个项目都有一定的小时数。 我们在同一 3 个月内拥有有限数量的资源(通常 < 100)。 每个资源每个月
我了解装箱和拆箱是关于强制转换(将实型转换为对象...将对象转换为实型)的。但是我不明白MSDN对Nullable的评价。这是我不明白的文字: When a nullable type is boxe
据我了解,Java 具有装箱(堆)和未装箱(堆栈)变量,如果我将装箱类型分配给未装箱类型,反之亦然,则涉及 (n) (un) 装箱成本。 拆箱比分配一个新的装箱对象便宜吗?如果以只读方式使用,盒装对象
装箱/拆箱和类型转换之间有什么区别? 这些术语似乎经常可以互换使用。 最佳答案 装箱是指将不可空值类型转换为引用类型或将值类型转换为其实现的某个接口(interface)(例如 int 到 IComp
给定一组项目,每个项目都有一个值,确定要包含在集合中的每个项目的数量,以使总值小于或等于给定限制,并且总值尽可能大。 例子: Product A = 4Product B = 3Product C =
我正在编写一个一维装箱程序。我只想要一个可能的垃圾箱。所以它不包括很多垃圾箱,它是唯一的一个。该程序仅搜索四边形组,如果四边形组不等于搜索数量则爆炸。我想搜索大于四边形的每个可能的组。在示例中,我们有
关闭。这个问题是not reproducible or was caused by typos .它目前不接受答案。 这个问题是由于错别字或无法再重现的问题引起的。虽然类似的问题可能是on-topi
我最近的代码包括很多 boxing and unboxing ,因为我的许多变量都是在运行时解析的。但是我读到装箱和拆箱在计算上非常昂贵,所以我想问一下是否还有其他方法可以对类型进行装箱/拆箱?这甚至
我的作业是装箱问题,要求我展示如何从优化版本解决问题的决策版本,反之亦然。我知道要解决决策版本,您只需获取优化版本中使用的 bin 数量并将其与指定的最大 bin 数量进行比较,但我如何使用决策版本来
这是在不使用外部库的情况下在 Java 中装箱/拆箱多维原始数组的最有效方法吗? private Float[][] toFloatArray(float[][] values) { Float
我有一个头疼的问题,感觉类似于经典的装箱问题,但我无法确定。任何帮助表示赞赏... 问题: 我有一组尺寸相同的产品,但有不同颜色的款式和不同的订单数量要求。 我可以任意组合包装,但我只能有规定数量的不
我有一个由 df.column.value_counts().sort_index() 生成的 Pandas 系列。 | N Months | Count | |------|------| |
大家可以向我解释一下 new 的性质以及 Integer 的使用 Integer i = new Integer(-10); Integer j = new Integer(-10); Integer
如果我错了,请纠正我,将值类型装箱转换为引用类型,那么为什么以下代码给出 10 输出而不是 12? public static void fun(Object obj) { o
如果我理解 CLR 装箱和处理可空值的方式,如 Boxing / Unboxing Nullable Types - Why this implementation? 中所述,我仍然有一些困惑。例如,
我经常使用 div 来装箱信息,但我注意到包装箱有时可能不会填满空间,这会导致来自其他包装器的元素进入箱区域。 例如: my info1 my Info2 看看这个例子 .topic {
目前我有这门课 public class Currency { private int _Amount; public Currency(){... } public Curr
我收集了 43 到 50 个数字,范围从 0.133 到 0.005(但大部分偏小)。如果可能的话,我想找到 L 和 R 之间总和非常接近的所有组合。* 蛮力法需要 243 到 250 步,这是不可行
我试图从性能的角度了解两种解决方案中的哪一种是首选。比如我有两段代码: 1) 装箱/拆箱 int val = 5; Session["key"] = val; int val2 = (int)Sess
通过 C# 在装箱/拆箱值类型上从 CLR 中提取 ... 关于装箱:如果可为空的实例不是null,CLR 会从可为空的实例中取出值并将其装箱。换句话说,值为 5 的 Nullable 装箱到值为
我是一名优秀的程序员,十分优秀!