我们知道基本数据类型包括byte, short, int, long, float, double, char, boolean,对应的包装类分别是Byte, Short, Integer, Long, Float, Double, Character, Boolean。关于基本数据类型的介绍可参考Java基础(一) 八大基本数据类型

那么为什么需要包装类?

JAVA是面向对象的语言,很多类和方法中的参数都需使用对象,但基本数据类型却不是面向对象的,这就造成了很多不便。

如:List<int> = new ArrayList<>();,就无法编译通过

为了解决该问题,我们引入了包装类,顾名思义,就是将基本类型“包装起来“,使其具备对象的性质,包括可以添加属性和方法,位于java.lang包下。

拆箱与装箱

既然有了基本数据类型和包装类,就必然存在它们之间的转换,如:

public static void main(String[] args) {
Integer a = 0;
for(int i = 0; i < 100; i++){
a += i;
}
}

将基本数据类型转为包装类的过程叫“装箱”;

将包装类转为基本数据类型的过程叫“拆箱”;

自动拆箱与自动装箱

Java为了简便拆箱与装箱的操作,提供了自动拆装箱的功能,这极大地方便了程序员们。那么到底是如何实现的呢?

上面的例子就是一个自动拆箱与装箱的过程,通过反编译工具我们得到,

public static void main(String[] args) {
Integer a = Integer.valueOf(0);
for (int i = 0; i < 100; i++) {
a = Integer.valueOf(a.intValue() + i);
}
}

我们不难发现,主要调用了两个方法,Integer.intValue()Integer.valueOf( int i) 方法

查看Integer源码,我们找到了对应代码:

/**
* Returns the value of this {@code Integer} as an
* {@code int}.
*/
public int intValue() {
return value;
}
/**
* Returns an {@code Integer} instance representing the specified
* {@code int} value. If a new {@code Integer} instance is not
* required, this method should generally be used in preference to
* the constructor {@link #Integer(int)}, as this method is likely
* to yield significantly better space and time performance by
* caching frequently requested values.
*
* This method will always cache values in the range -128 to 127,
* inclusive, and may cache other values outside of this range.
*
* @param i an {@code int} value.
* @return an {@code Integer} instance representing {@code i}.
* @since 1.5
*/
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}

很明显,我们我们得出,Java帮你隐藏了内部细节。

拆箱的过程就是通过Integer 实体调用intValue()方法;

装箱的过程就是调用了 Integer.valueOf(int i) 方法,帮你直接new了一个Integer对象

那么哪些地方会进行自动拆装箱?

其实很简单

1.添加到集合中时,进行自动装箱

2.涉及到运算的时候,“加,减,乘, 除” 以及 “比较 equals,compareTo”,进行自动拆箱

注意的点

在上述的代码中,关于Integer valueOf(int i)方法中有IntegerCache类,在自动装箱的过程中有个条件判断

if (i >= IntegerCache.low && i <= IntegerCache.high)

结合注释

This method will always cache values in the range -128 to 127,

inclusive, and may cache other values outside of this range.

大意是:该方法总是缓存-128 到 127之间的值,同时针对超出这个范围的值也是可能缓存的。

那么为什么可能缓存?其实在IntegerCache源码中可以得到答案

String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
try {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
} catch( NumberFormatException nfe) {
// If the property cannot be parsed into an int, ignore it.
}
}

因为缓存最大值是可以配置的。这样设计有一定好处,我们可以根据应用程序的实际情况灵活地调整来提高性能。

与之类似还有:

Byte与ByteCache,缓存值范围-128到127,固定不可配置

Short与ShortCache,缓存值范围-128到127,固定不可配置

Long与LongCache,缓存值范围-128到127,固定不可配置

Character与CharacterCache,缓存值范围0到127,固定不可配置

Java基础(二) 基本类型数据类型、包装类及自动拆装箱的更多相关文章

  1. 【Java基础】基本类型的包装类作为参数传递是值传递还是引用传递

    突然想到这个问题,然后做了下实验,下面以Integer来讲解,其他的忽略: import java.util.Iterator; /** * Created by lili on 15/9/24. * ...

  2. Java包装类的自动拆装箱

    题目: Integer i = 42; Long l = 42l; Double d = 42.0; 下面为true的是 A.(i == l) B.(i == d) C.(l == d) D.i.eq ...

  3. Java面试题总结之Java基础(二)

    Java面试题总结之Java基础(二) 1.写clone()方法时,通常都有一行代码,是什么? 答:super.clone(),他负责产生正确大小的空间,并逐位复制. 2.GC 是什么? 为什么要有G ...

  4. Java基础进阶:APi使用,Math,Arrarys,Objects工具类,自动拆装箱,字符串与基本数据类型互转,递归算法源码,冒泡排序源码实现,快排实现源码,附重难点,代码实现源码,课堂笔记,课后扩展及答案

    要点摘要 Math: 类中么有构造方法,内部方法是静态的,可以直接类名.方式调用 常用: Math.abs(int a):返回参数绝对值 Math.ceil(double a):返回大于或等于参数的最 ...

  5. Java入土--Java基础(二)

    Java基础(二) 接上一讲,我们接着来聊聊Java的一些基础知识,下一讲就会进行流程的控制. 类型转换 首先呢,是类型的转换,接上一个内容的数据类型,类型转换就是数据类型更进一步的应用. 由于Jav ...

  6. java基础04-数据类型扩展及面试题

    java基础04-数据类型扩展及面试题讲解 public class demo02 { public static void main(String[] args){ // 一.整数拓展: 进制 二进 ...

  7. 【转】Java基础笔记 – 枚举类型的使用介绍和静态导入--不错

    原文网址:http://www.itzhai.com/java-based-notes-introduction-and-use-of-an-enumeration-type-static-impor ...

  8. Java基础之枚举类型Enum的使用

    Java基础之枚举类型Enum的使用 定义 public enum AccruedCleanEnum { SPREAD("1","发票"),OTHER(&quo ...

  9. java的数据类型、自动拆装箱、字面量

    java 中的数据类型分为两大类:值类型(基本数据类型)和引用类型(复合数据类型)  值类型分为 1,整数类型(byte,short,int,long) 2,浮点类型(float,double) 3, ...

随机推荐

  1. Android菜鸟的成长笔记(18)——绑定本地Service并与之通信

    在上一篇中介绍了Service与Activity的区别及Service两种启动方式中的第一种启动方式startService(). 我们会发现用startService().stopService() ...

  2. 《node.js开发指南》第五章与新版Node变化太大的一些问题

    1.在win下,命令行工具express -h无效,因为4.x版本的express需要安装express-generator才可以使用express命令,npm install -g express- ...

  3. JDK源代码学习系列03----StringBuffer+StringBuilder

                         JDK源代码学习系列03----StringBuffer+StringBuilder 因为前面学习了StringBuffer和StringBuilder的父类 ...

  4. windows通过使用xShell远程linux上传文件

    上传文件rz与sz命令,远程linux您需要在系统上安装lrzsz工具包 安装例如,下面的: [xxxx@xxxx /]# yum install lrzsz 注意:我用命令yum,假设在Intern ...

  5. UML静态视图——类图、对象图、包图

    绘画类的最重要的图是抽象类.让我们回顾一下类的基本内容. 一.分类 1.类的概念: 面向对象编程的类是一个基本概念.类是具有相同特性的.办法.集合语义和一组对象的关系. 2.类分类: 实体类:保存要放 ...

  6. OpenCV中基于HOG特征的行人检测

    目前基于机器学习方法的行人检测的主流特征描述子之一是HOG(Histogram of Oriented Gradient, 方向梯度直方图).HOG特征是用于目标检测的特征描述子,它通过计算和统计图像 ...

  7. C# ?和??使用讲解

    原文:C# ?和??使用讲解 场景1:使用?定义可空类型 众所周知,C#中的值类型是不可以为null的,如果必须为null,则需要将变量定义为可空类型,如下所示: int? age = null; 场 ...

  8. matlab 各种文件的读取(及读写问题的解决)

    0. 文本文件 load('**.mat') load('**.mat', '-ascii') load('-mat', filename) load('-ascii', filename) 1. 音 ...

  9. STM32 模拟I2C (STM32F051)

    /** ****************************************************************************** * @file i2c simu. ...

  10. 【转载】使用Docker Hub官方gcc:latest镜像编译C/C++程序以及缩小镜像的方法

    摘要:使用Docker Hub官方gcc:latest镜像(1.2GB)编译C/C++程序,以及缩小镜像的方法. 方法1: 在gcc容器里编译C/C++程序 将C/C++代码运行在gcc容器内的最简单 ...