一、Java数据类型

1、在说装箱与拆箱之前,先说一下Java的基本数据类型,Java从数据类型上可以划分为值类型引用类型,值类型是四类八种,分别是:

  • 整数型:byte̵,short̵,int̵,long
  • 浮点型:float,double
  • 字符型:char
  • 布尔型:boolean
数据类型 内存 默认值 包装类
byte 8位 0 Byte
short 16位 0 short
int 32位 0 Integer
long 64位 0L或0l Long
float 32位 0.0F或0.0f Float
double 64位 0.0D或0.0d Double
char 16位 \u0000 Character
boolean 8位 flase Boolean

2、引用类型:

  • 数组
  • 类(class)
  • 接口(Interface)
  • 枚举(enum)

3、值类型与引用类型的区别

  1. 从概念方面上来说:

    • 值类型:变量名指向具体的值
    • 引用类型:变量名指向数据对象的内存地址
  2. 从内存构建方面上来说:
    • 值类型:变量在声明之后,Java就会立刻分配给它内存空间
    • 引用类型:它以特殊的方式(类似C指针)指向对象实体,这类变量声明时不会分配内存,只是存储
  3. 从使用方面上来说:
    • 值类型:使用时需要赋具体值,判断时用 ” == “号
    • 引用类型:使用时可以赋null,判断时使用 equals 方法

二、Java数据类型转换

1、自动转换

  • 定义:程序在执行过程中“悄然”进行的转换,不需要用户提前声明,一般是从位数低的类型向位数高的类型转换

  • 优先关系:按从低到高的顺序转换。不同类型数据间的优先

    关系如下:

    • 低--------------------------------------------->高
    • byte,short,char-> int -> long -> float -> double
  • 转换规则:

    运算中,不同类型的数据先转化为同一类型,然后进行运算

    操作数1类型 操作数2类型 转换后的类型
    byte、short、char int int
    byte、short、char、int long long
    byte、short、char、int、long float float
    byte、short、char、int、long、float double double

2、强制转换

  • 定义:强制类型转换则必须在代码中声明,转换顺序不受限制

  • 格式:在需要转型的数据前加上“( )”,然后在括号内加入需要转化的数据类型

  • 结果:精度可能会丢失,也可能更加精确

    int x;
    double y; x = (int)3.14 + (int)5.20 //精度丢失
    y = (double)x + (double)8 //精度提升 输出:x = 8;y = 16.0

三、Java之装箱与拆箱

1、包装类

  • Java是面向对象语言,号称万事万物皆对象,因此,8种基本数据类型有了对应的类,这就是包装类

2、什么是装箱与拆箱

  • 装箱:将值类型装换成引用类型的过程

  • 拆箱:将引用类型转换成值类型的过程

  • 自动装箱:

    int x = 3;
    Integer y = x; //int --> Integer,Integer y = x <==> Integer y = Integer.valueOf(x)
  • 自动拆箱:

    Integer x = new Integer(5);
    int y = x; //Integer --> int,int y = x <==> int y = x.intValue()

3、装箱和拆箱是如何实现的

  • 装箱过程是通过调用包装器的valueOf方法实现的
  • 拆箱过程是通过调用包装器的 xxxValue方法实现的。(xxx代表对应的基本数据类型)

4、注意点:

  1. 大量使用自动拆装箱会使性能降低,还会造成大量的内存消耗
  2. 在重载方法中,可能出现问题
    List<Integer> list = new ArrayList<>();
    Integer x,y,z;
    x = 1;y = 2;z = 4;
    list.add(x);list.add(y);list.add(z); list.remove(2);

    在上面这段代码中ArrayList.remove方法有两个重载方法,那么list.remove(2)是调用了哪个方法,remove掉的是值为2的对象,还是remove了index为2,值为4的那个对象呢?

    在这种情况下,编译器不会进行自动拆装箱,所以调用的是remove(int index),index为2值为4的这个Integer对象会被remove.

    如果要调用 remove(Object o)的方法,应该这么写 list.remove(y)

  3. 缓存值问题
  • 案例解析:

    Integer i1 = 100;
    Integer i2 = 100;
    Integer i3 = 200;
    Integer i4 = 200;
    System.out.println(i1==i2);
    System.out.println(i3==i4); Output: true false
  • 观察源码:

    Intteger.valueOf方法

    public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
    return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
    }

    IntegerCache类

    private static class IntegerCache {
    static final int low = -128;
    static final int high;
    static final Integer cache[]; static {
    // high value may be configured by property
    int h = 127;
    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.
    }
    }
    high = h; cache = new Integer[(high - low) + 1];
    int j = low;
    for(int k = 0; k < cache.length; k++)
    cache[k] = new Integer(j++); // range [-128, 127] must be interned (JLS7 5.1.7)
    assert IntegerCache.high >= 127;
    } private IntegerCache() {}
    }

    从源码可以看出,在通过valueOf方法创建Integer对象的时候,如果数值在[-128,127]之间,便返回指向IntegerCache.cache中已经存在的对象的引用;否则创建一个新的Integer对象

  • Byte、Short、Integer、Long四种包装类默认创建了数值为[-128,127]的相应类型的缓存数据,但是超出此范围仍会创建新的对象。

  • Character默认会创建[0,127]的响应类型的缓存数据

  • 两种浮点型没有实现常量池技术,在某个范围内的整型数值的个数是有限的,而浮点数却不是

    包装类 常量池 常量池范围
    Byte 存在 [-128,127]
    Short 存在 [-128,127]
    Integer 存在 [-128,127]
    Long 存在 [-128,127]
    Character 存在 [0,127]
    Float 不存在
    Double 不存在
  • 注意点:

    • 当 "=="运算符的两个操作数都是 包装器类型的引用,则是比较指向的是否是同一个对象,而如果其中有一个操作数是表达式(即包含算术运算)则比较的是数值(即会触发自动拆箱的过程)
    • 对于包装器类型,equals方法并不会进行类型转换
    • 算术运算会触发装箱与拆箱过程
  • 注意点:

    • 当 "=="运算符的两个操作数都是 包装器类型的引用,则是比较指向的是否是同一个对象,而如果其中有一个操作数是表达式(即包含算术运算)则比较的是数值(即会触发自动拆箱的过程)
    • 对于包装器类型,equals方法并不会进行类型转换
    • 算术运算会触发装箱与拆箱过程

参考文章:https://www.cnblogs.com/dolphin0520/p/3780005.html

深入理解Java中的装箱与拆箱的更多相关文章

  1. 第六节:详细讲解Java中的装箱与拆箱及其字符串

    前言 大家好,给大家带来详细讲解Java中的装箱与拆箱及其字符串的概述,希望你们喜欢 装箱与拆箱 封装类有:Byte , short , Integer , Character , long , Fl ...

  2. 深入剖析Java中的装箱和拆箱

    深入剖析Java中的装箱和拆箱 自动装箱和拆箱问题是Java中一个老生常谈的问题了,今天我们就来一些看一下装箱和拆箱中的若干问题.本文先讲述装箱和拆箱最基本的东西,再来看一下面试笔试中经常遇到的与装箱 ...

  3. 从别人那淘的知识 深入剖析Java中的装箱和拆箱

    (转载的海子的博文   海子:http://www.cnblogs.com/dolphin0520/) 深入剖析Java中的装箱和拆箱 自动装箱和拆箱问题是Java中一个老生常谈的问题了,今天我们就来 ...

  4. [ 转载 ]学习笔记-深入剖析Java中的装箱和拆箱

    深入剖析Java中的装箱和拆箱 自动装箱和拆箱问题是Java中一个老生常谈的问题了,今天我们就来一些看一下装箱和拆箱中的若干问题.本文先讲述装箱和拆箱最基本的东西,再来看一下面试笔试中经常遇到的与装箱 ...

  5. 【转】深入剖析Java中的装箱和拆箱

    深入剖析Java中的装箱和拆箱 自动装箱和拆箱问题是Java中一个老生常谈的问题了,今天我们就来一些看一下装箱和拆箱中的若干问题.本文先讲述装箱和拆箱最基本的东西,再来看一下面试笔试中经常遇到的与装箱 ...

  6. (转)深入剖析Java中的装箱和拆箱

    转:https://www.cnblogs.com/dolphin0520/p/3780005.html 深入剖析Java中的装箱和拆箱 自动装箱和拆箱问题是Java中一个老生常谈的问题了,今天我们就 ...

  7. java语法糖3 深入剖析Java中的装箱和拆箱

    装箱 在Java SE5之前,如果要生成一个数值为10的Integer对象,必须这样进行: Integer i = new Integer(10); 而在从Java SE5开始就提供了自动装箱的特性, ...

  8. 深入剖析Java中的装箱和拆箱(转)

    自动装箱和拆箱问题是Java中一个老生常谈的问题了,今天我们就来一些看一下装箱和拆箱中的若干问题.本文先讲述装箱和拆箱最基本的东西,再来看一下面试笔试中经常遇到的与装箱.拆箱相关的问题. 以下是本文的 ...

  9. 深入剖析Java中的装箱和拆箱(缓存池技术)

    以下是本文的目录大纲: 一.什么是装箱?什么是拆箱? 简单一点说,装箱就是  自动将基本数据类型转换为包装器类型:拆箱就是  自动将包装器类型转换为基本数据类型. 二.装箱和拆箱是如何实现的 1:反编 ...

随机推荐

  1. C#LeetCode刷题之#67-二进制求和(Add Binary)

    问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/3929 访问. 给定两个二进制字符串,返回他们的和(用二进制表示) ...

  2. 调试备忘录-RS485 MODBUS RTU协议简述

    目录--点击可快速直达 目录 写在前面 先简单说下什么是MODBUS? 参考文章 写在前面 最近在做和物联网有关的小项目,有一个传感器通讯用到了RS485 MODBUS RTU协议,所以就写个随笔记录 ...

  3. python基本数据类型(三)

    字典{} 冒号前面是key(键)冒号后面是values(值)  键:值 ==键值对 1.索引 s={ 'name':'lifei', 'age':'', 'sex':'man' } print(s[' ...

  4. 树上的等差数列 [树形dp]

    树上的等差数列 题目描述 给定一棵包含 \(N\) 个节点的无根树,节点编号 \(1\to N\) .其中每个节点都具有一个权值,第 \(i\) 个节点的权值是 \(A_i\) . 小 \(Hi\) ...

  5. C++指针变量的基本写法

    指针变量与应用——动态数组 在C++中,有一种神奇的变量,它不可以表示一个值,但是可以表示某个元素的地址,通过地址来访问这个元素. 打个比方:你有一张地图和一个坐标,你就可以通过访问这个坐标来达到你访 ...

  6. cvsnt 和wincvs 的安装配置既简单操作 2007-07-28 11:33

    CVSNT 配置 版本:CVSNT 2.5.03(Scorpio)Build 2382 安装过程:简单一路next即可. 配置: (一)我们先准备好两个目录,分别是KHRoot,和KHTemp.KHR ...

  7. xss-labs 通关学习笔记

    xss-labs 学习 By:Mirror王宇阳 time:2020/04/06 level1 我们进入到这个页面之后,快速关注到几个点,Xss注重的输入点,这里的输入点首先在URL栏中找到了name ...

  8. phpstudy后门利用复现

    一.漏洞位置 程序自带的PHP的php_xmlrpc.dll模块中有隐藏后门,受影响的版本有phpstudy2016(php5.2/5.4).phpstudy2018(php5.2/5.4)等版本. ...

  9. centos7 编译安装 redis-6.0.5

    安装redis sudo yum install redis centos自带的redis才3.2 太旧了所以使用源码编译 需要先安装gcc新版才能编译 centos7 默认的 gcc 版本为:4.8 ...

  10. Java多线程同步_synchronized

    1.synchronized是什么?synchronized是Java中的关键字,是一种同步锁.它修饰的对象有以下几种:1. 修饰一个代码块,被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起 ...