你不知道的基本数据类型和包装类

基本数据类型

Java 基本数据按类型可以分为四大类:布尔型、整数型、浮点型、字符型,这四大类包含 8 种基本数据类型。

布尔型:boolean

整数型:byte、short、int、long

浮点型:float、double

字符型:char

8 种基本类型取值如下:

数据类型代表含义默认值取值包装类

boolean布尔型false0(false) 到 1(true)Boolean

byte字节型(byte)0﹣128 到 127Byte

char字符型'\u0000'(空)'\u0000' 到 '\uFFFF'Character

short短整数型(short)0-215215 到 215215

﹣1Short

int整数型0﹣231231 到 231231﹣1Integer

long长整数型0L﹣263263 到 263263﹣1Long

float单浮点型0.0f1.4e-45 到 3.4e+38Float

double双浮点型0.0d4.9e-324 到 1.798e+308Double

除 char 的包装类 Character 和 int 的包装类 Integer 之外,其他基本数据类型的包装类只需要首字母大写即可。包装类的作用和特点,本文下半部分详细讲解。

我们可以在代码中,查看某种类型的取值范围,代码如下:

public static void main(String[] args) {

   // Byte 取值:-128 ~ 127

   System.out.println(String.format("Byte 取值:%d ~ %d", Byte.MIN_VALUE, Byte.MAX_VALUE));

   // Int 取值:-2147483648 ~ 2147483647

   System.out.println(String.format("Int 取值:%d ~ %d", Integer.MIN_VALUE, Integer.MAX_VALUE));

}

包装类型

我们知道 8 种基本数据类型都有其对应的包装类,因为 Java 的设计思想是万物既对象,有很多时候我们需要以对象的形式操作某项功能,比如说获取哈希值(hashCode)或获取类(getClass)等。

那包装类特性有哪些?

1. 功能丰富

包装类本质上是一个对象,对象就包含有属性和方法,比如 hashCode、getClass 、max、min 等。

2. 可定义泛型类型参数

包装类可以定义泛型,而基本类型不行。

比如使用 Integer 定义泛型,代码:

List<Integer> list = new ArrayList<>();

如果使用 int 定义就会报错,代码:

List list = new ArrayList<>();  // 编译器代码报错

3. 序列化

因为包装类都实现了 Serializable 接口,所以包装类天然支持序列化和反序列化。比如 Integer 的类图如下:

4. 类型转换

包装类提供了类型转换的方法,可以很方便的实现类型之间的转换,比如 Integer 类型转换代码:

String age = "18";

int ageInt = Integer.parseInt(age) + 2;

// 输出结果:20

System.out.println(ageInt);

5. 高频区间的数据缓存

此特性为包装类很重要的用途之一,用于高频区间的数据缓存,以 Integer 为例来说,在数值区间为 -128~127 时,会直接复用已有对象,在这区间之外的数字才会在堆上产生。

我们使用 == 对 Integer 进行验证,代码如下:

public static void main(String[] args) {

       // Integer 高频区缓存范围 -128~127

       Integer num1 = 127;

       Integer num2 = 127;

       // Integer 取值 127 == 结果为 true(值127 num1==num2 => true)

       System.out.println("值127 num1==num2 => " + (num1 == num2));

       Integer num3 = 128;

       Integer num4 = 128;

       // Integer 取值 128 == 结果为 false(值128 num3==num4 => false)

       System.out.println("值128 num3==num4 => " + (num3 == num4));

   }

从上面的代码很明显可以看出,Integer 为 127 时复用了已有对象,当值为 128 时,重新在堆上生成了新对象。

为什么会产生高频区域数据缓存?我们查看源码就能发现“线索”,源码版本 JDK8,源码如下:

public static Integer valueOf(int i) {

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

   return IntegerCache.cache[i + (-IntegerCache.low)];

  return new Integer(i);

}

由此可见,高频区域的数值会直接使用已有对象,非高频区域的数值会重新 new 一个新的对象。

各包装类高频区域的取值范围:

Boolean:使用静态 final 定义,就会返回静态值

Byte:缓存区 -128~127

Short:缓存区 -128~127

Character:缓存区 0~127

Long:缓存区 -128~127

Integer:缓存区 -128~127

包装类的注意事项

int 的默认值是 0,而 Integer 的默认值是 null。

推荐所有包装类对象之间的值比较使用 equals() 方法,因为包装类的非高频区数据会在堆上产生,而高频区又会复用已有对象,这样会导致同样的代码,因为取值的不同,而产生两种截然不同的结果。代码示例:

public static void main(String[] args) {

   // Integer 高频区缓存范围 -128~127

   Integer num1 = 127;

   Integer num2 = 127;

   // Integer 取值 127 == 结果为 true(值127 num1==num2 => true)

   System.out.println("值127 num1==num2 => " + (num1 == num2));

   Integer num3 = 128;

   Integer num4 = 128;

   // Integer 取值 128 == 结果为 false(值128 num3==num4 => false)

   System.out.println("值128 num3==num4 => " + (num3 == num4));

   // Integer 取值 128 equals 结果为 true(值128 num3.equals(num4) => true)

   System.out.println("值128 num3.equals(num4) => " + num3.equals(num4));

}

Float 和 Double 不会有缓存,其他包装类都有缓存。

Integer 是唯一一个可以修改缓存范围的包装类,在 VM optons 加入参数:

-XX:AutoBoxCacheMax=666 即修改缓存最大值为 666 。

示例代码如下:

public static void main(String[] args) {

   Integer num1 = -128;

   Integer num2 = -128;

   System.out.println("值为-128 => " + (num1 == num2));

   Integer num3 = 666;

   Integer num4 = 666;

   System.out.println("值为666 => " + (num3 == num4));

   Integer num5 = 667;

   Integer num6 = 667;

   System.out.println("值为667 => " + (num5 == num6));

}

执行结果如下:

值为-128 => true

值为666 => true

值为667 => false

由此可见将 Integer 最大缓存修改为 666 之后,667 不会被缓存,而 -128~666 之间的数都被缓存了。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343

推荐阅读更多精彩内容

  • 第01章 JAVA简介第02章 基础语法第02章 递归补充第03章 面向对象第04章 异常处理第05章 数组第06...
    顺毛阅读 508评论 0 1
  • 包装类(包裹类 Wrapper) : 定义Java 针对八种 基本数据类型 提供了相应的包装类 目的使得可以创建对...
    Finlay_Li阅读 274评论 0 0
  • 其他更多java基础文章:java基础学习(目录) 转载自 Java 源码学习系列(三)——Integer学习的过...
    Hiwayz阅读 698评论 0 0
  • Go语言数据类型 Go语言本质是用C语言编写的一套高级开发语言, 所以Go语言中的数据类型大部分都是由C语言演变而...
    极客江南阅读 916评论 0 6
  • 我市天龙汽车站的站长。前几天下去检查工作时。我发现乘客上车时比较拥挤,尤其是那些抱着小孩儿又踢东西的妇女上车。非常...
    张嘉鑫1阅读 134评论 0 0