Java源码解读(一) 8种基本类型对应的封装类型

Wesley13
• 阅读 700

说起源码其实第一个要看的应该是我们的父类Object,这里就不对它进行描述了大家各自对其进行阅读即可(其中留意wait()方法可能会存在虚假唤醒的情况)。

一、八种基本类型

接下来介绍我们的八种基本类型(这个大家都知道吧):char、byte、short、int、long、float、double、boolean。这里也不太描述其过多的东西,只说些要特别注意的事项(如果我这存在遗落的,欢迎大家补充):

1、byte、short、char 不能进行含有变量的运算符运算(正常的运算符),都要求进行强转,因为都有范围限制。

Java源码解读(一) 8种基本类型对应的封装类型

*但是可以进行+= 和自增增减的操作。*

Java源码解读(一) 8种基本类型对应的封装类型

2、自动转型等级:byte,short,char(同级)-> int -> long -> float -> double (由低精度到高精度),同级不能自动转型,需要强制转换

二、八种封装类型

先说共同点:

  • equals方法:

只有同一类型的才能作比较,然后再比较其值。源码以short为例,其它几个都一样。

public boolean equals(Object obj) {
        if (obj instanceof Short) {
            return value == ((Short)obj).shortValue();
        }
        return false;
    }

所以不同类型的不管值是否相等都是false;

    @Test
    public void testEquals(){
        Short num1 = 1;
        Integer num2 = 1;
        Long num3 = 1L;
        System.out.println(num1.equals(num2));//false
        System.out.println(num2.equals(num3));//false
    }
  •  直接赋值时,都会调用valueOf方法。所以要注意其的源代码。

不同点:

1、Character

  • 注意valueOf中代码,它缓存了ASCII码0~127的字符。其他均会创建实例。

Java源码解读(一) 8种基本类型对应的封装类型

2、Byte

  • 范围是-128~127,所以超过这个范围会要求强制转换。如果使用Byte(String s)创建实例的话,超过范围会抛出异常:NumberFormatException

  • 注意valueOf中的代码,它缓存了-128~127,所以直接赋值是不创建新实例的。Java源码解读(一) 8种基本类型对应的封装类型

    @Test
    public void testByte(){
        //byte的范围是-128~127,针对byte如果赋值不在范围eclipse会要求强制转型成byte.
        //封装类型Byte  new Byte("128")当使用字符串创建实例时,其中值超过范围会报错NumberFormatException。
        byte b1 = 12;
        Byte b2 = 12;//(byte)129;//超过范围要求强转
        Byte b3 = 12;//(byte)129;
        //Byte b4 = new Byte("128");//抛出异常
        Byte b4 = new Byte("12");//抛出异常
        System.out.println(b1 == b2);//true
        System.out.println(b2 == b3);//true
        System.out.println(b2 == b4);//false
    }
    

3、Short

  • 跟byte的第一点一样,只是范围(-32768 ~ 32767)不一样

  • 注意valueOf方法,它缓存了-128127的值,超过这个范围(-128127)就会创建新的实例。Java源码解读(一) 8种基本类型对应的封装类型

  • 基于第二种情况,不便于进行循环遍历复制操作,否则超过范围就会多个实例,影响内存。

    @Test
    public void testShort(){
        //1、short范围:-32768 ~ 32767
        Short s = new Short("32767");//超过范围会报错 NumberFormatException
        s = new Short((short)327671);//超过这个范围自动转换
        
        //2、装箱与拆箱 自动转型
        short s1 = 12;
        Short s2 = new Short(s1);//手动装箱
        System.out.println("s1 == s2:" + (s1 == s2));//自动拆箱  true
        
        //3、valueOf方法缓存了-128~127的范围,超过这个范围就要另外创建这个实例。
        Short s3 = 12;
        Short s4 = 12;
        Short s5 = 128;
        Short s6 = 128;
        System.out.println("s3 == s4:" + (s3 == s4)); //true
        System.out.println("s5 == s6:" + (s5 == s6)); //false
        
        //4、由于上面这个特性,所以这种包装类型不能在循环遍历中赋值。不然其值超过这个范围的话,就会创建新的对象,如果很多的话,就会创建很多对象。浪费空间。
    }
    

4、Integer

  • 承受的值要注意范围(-2147483648 ~ 2147483647 ),不要求强转。

  • 注意valueOf方法,跟Short的方法一样,缓存了-128127的值,超过这个范围(-128127)就会创建新的实例。Java源码解读(一) 8种基本类型对应的封装类型

  • 基于第二种情况,不便于进行循环遍历复制操作,否则超过范围就会多个实例,影响内存。

       @Test
        public void testInteger(){
            //1、Integer范围:-2147483648  ~ 2147483647 
            //后面与Short一样
            //2、装箱与拆箱 自动转型
            int s1 = 12;
            Integer s2 = new Integer(s1);//手动装箱
            System.out.println("s1 == s2:" + (s1 == s2));//自动拆箱 true
            
            //3、valueOf方法缓存了-128~127的范围,超过这个范围就要另外创建这个实例。
            Integer s3 = 12;
            Integer s4 = 12;
            Integer s5 = 128;
            Integer s6 = 128;
            System.out.println("s3 == s4:" + (s3 == s4));//true
            System.out.println("s5 == s6:" + (s5 == s6));//false
            //4、由于上面这个特性,所以这种包装类型不能在循环遍历中赋值。不然其值超过这个范围的话,就会创建新的对象,如果很多的话,就会创建很多对象。浪费空间。
        }
    

5、Long

  • 承受的值要注意范围(-9223372036854775808 ~ 9223372036854775807 ),不要求强转。

  • 注意valueOf方法,跟Short的方法一样,缓存了-128127的值,超过这个范围(-128127)就会创建新的实例。Java源码解读(一) 8种基本类型对应的封装类型

  • 基于第二种情况,不便于进行循环遍历复制操作,否则超过范围就会多个实例,影响内存。

        @Test
        public void testLong(){
            //范围就不考虑了。
            //同样、valueOf方法缓存了-128~127的范围,超过这个范围就要另外创建这个实例。
            Long s3 = 12L;
            Long s4 = 12L;
            Long s5 = 128L;
            Long s6 = 128L;
            System.out.println("s3 == s4:" + (s3 == s4));//true
            System.out.println("s5 == s6:" + (s5 == s6));//false
            //由于上面这个特性,所以这种包装类型不能在循环遍历中赋值。不然其值超过这个范围的话,就会创建新的对象,如果很多的话,就会创建很多对象。浪费空间。
        }
    

 

6、Float

  • 承受的值要注意范围(-1.4E-45~ 3.4028235E38),不要求强转。

  • 注意valueOf方法,跟前面的Short、Integer、Long不一样了,直接创建实例。Java源码解读(一) 8种基本类型对应的封装类型

  • 所以相等值的两个变量 ==运算是false.

  • 不要做加减法运算。精度(9位)问题。

    @Test
    public void testFloat(){
        //没有特殊要注意的,其他跟上面一样
        int f = 1;
        Float f1 = 1F;
        Float f2 = new Float(f);
        System.out.println(f == f1);//true
        System.out.println(f1 == f2);//false
        //注意不要用这类型做加减运算,精度问题会影响。
        System.out.println(f1 - 0.1f*9);//0.099999964
    }
    

7、Double

  • 承受的值要注意范围,不要求强转。
  • 注意valueOf方法,与float一样,直接创建实例。
  • Java源码解读(一) 8种基本类型对应的封装类型

所以相等值的两个变量 ==运算是false.

  • 不要做加减法运算。精度(17位)问题。

    @Test
    public void testDouble(){
        //注意不要用这类型做加减运算,精度问题会影响。
        System.out. println(1.0 - 0.1*9);//0.09999999999999998
        //valueof 
        Double i1 = 100.0;
        Double i2 = 100.0;
        Double i3 = 200.0;
        Double i4 = 200.0;
        System.out.println(i1==i2);//false
        System.out.println(i3==i4);//false
    }
    

8、Boolean

  • valueof方法

Java源码解读(一) 8种基本类型对应的封装类型

缓存了两个方法,所以如果是同样的赋值,== 运算是为true的。

    @Test
    public void testEquals(){
        Short num1 = 1;
        Integer num2 = 1;
        Long num3 = 1L;
        System.out.println(num1.equals(num2));//false
        System.out.println(num2.equals(num3));//false
    }

 三、案例分析

  猜猜下面各个输出的结果是什么:

@Test
    public void test1(){
        Integer a = 1;
        Integer b = 2;
        Integer c = 3;
        Integer d = 3;
        Integer e = 321;
        Integer f = 321;
        Long g = 3L;
        Long h = 2L;
         
        System.out.println(c==d);
        System.out.println(e==f);
        System.out.println(c==(a+b));
        System.out.println(c.equals(a+b));
        System.out.println(g==(a+b));
        System.out.println(g.equals(a+b));
        System.out.println(g.equals(a+h));
    }

  其中会涉及到拆箱与装箱(自行弄懂)的问题。针对个别解析如下:

  c==(a+b) :a+b都会拆箱成int然后相加,所以c也会自动拆箱比较。

  g==(a+b):同理,a+b都会拆箱成int然后相加,g会拆箱成long类型。所以基本类型比较只要比较其值即可。

  g.equals(a+b):先拆箱a+b再装箱还是Integer,这里不会自动转型。Long类型的equals判断不是同一类型直接返回false

  g.equals(a+h):同上,先拆箱a+h再装箱(这里会自动向上转型)为Long,所以同类型的比较值又相等,这里返回true.

  最终结果如下:

true
false
true
true
true
false
true
点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
初级Java开发工程师!绝密文档,面试手册全面突击!!!秋招已经到来
这里我要明说一下,不是Java初级和学习Java的千万不要乱看,否则你会怀疑人生,因为会浪费你时间啊!!!本次考点是Java初级开发工程师面试必备的一些东西!!!1、数据类型基本类型cbyte/8、short/16、int/32、long/64、boolean/、char/16、float/32、double/64boolean只有两个值,true、f
Wesley13 Wesley13
3年前
java 知识点 小结
1. Java8种基本类型:byte char shortint long double float booleanByte:8位Short:16位Int:32位Long:64位Float:32位Double:64位2. ListsetmapList:有序;
Stella981 Stella981
3年前
JVM调优总结(2):一些概念(下)
Java对象的大小基本数据的类型的大小是固定的,这里就不多说了。对于非基本类型的Java对象,其大小就值得商榷。在Java中,一个空Object对象的大小是8byte,这个大小只是保存堆中一个没有任何属性的对象的大小。看下面语句:ObjectobnewObject();有了Object对象的
Stella981 Stella981
3年前
JVM调优总结一
数据类型   Java虚拟机中,数据类型可以分为两类:基本类型和引用类型。基本类型的变量保存原始值,即:他代表的值就是数值本身;而引用类型的变量保存引用值。“引用值”代表了某个对象的引用,而不是对象本身,对象本身存放在这个引用值所表示的地址的位置。基本类型包括:byte,short,int,long,cha
Wesley13 Wesley13
3年前
JAVA基本类型和引用类型
一、基本数据类型java中一共分为8种基本数据类型:byte、short、int、long、float、double、char、boolean,其中byte、short、int、long是整型。float、double是浮点型,char是字符型,boolean是布尔型。二、引用类型j
小万哥 小万哥
1年前
Java基础知识:面试官必问的问题
数据类型基本类型byte/8char/16short/16int/32float/32long/64double/64boolean/boolean只有两个值:true、false,可以使用1bit来存储,但是具体大小没有明确规定。JVM会在编译时期将bo
Java服务总在半夜挂,背后的真相竟然是... | 京东云技术团队
最近有用户反馈测试环境Java服务总在凌晨00:00左右挂掉,用户反馈Java服务没有定时任务,也没有流量突增的情况,Jvm配置也合理,莫名其妙就挂了
小万哥 小万哥
5个月前
Kotlin 数据类型详解:数字、字符、布尔值与类型转换指南
Kotlin中变量类型由值决定,如Int、Double、Char、Boolean、String。通常可省略类型声明,但有时需指定。数字类型分整数(Byte,Short,Int,Long)和浮点(Float,Double),默认整数为Int,浮点为Double。布尔值是true或false,Char用单引号,字符串用双引号。数组和类型转换将在后续讨论,转换需用特定函数。