Java源码解读(一) 8种基本类型对应的封装类型
说起源码其实第一个要看的应该是我们的父类Object,这里就不对它进行描述了大家各自对其进行阅读即可(其中留意wait()方法可能会存在虚假唤醒的情况)。
一、八种基本类型
接下来介绍我们的八种基本类型(这个大家都知道吧):char、byte、short、int、long、float、double、boolean。这里也不太描述其过多的东西,只说些要特别注意的事项(如果我这存在遗落的,欢迎大家补充):


二、八种封装类型
先说共同点:
- equals方法:
public boolean equals(Object obj) {
if (obj instanceof Short) {
return value == ((Short)obj).shortValue();
}
return 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方法。所以要注意其的源代码。
- 注意valueOf中代码,它缓存了ASCII码0~127的字符。其他均会创建实例。

- 范围是-128~127,所以超过这个范围会要求强制转换。如果使用Byte(String s)创建实例的话,超过范围会抛出异常:NumberFormatException
- 注意valueOf中的代码,它缓存了-128~127,所以直接赋值是不创建新实例的。


@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
}
- 跟byte的第一点一样,只是范围(-32768 ~ 32767)不一样
- 注意valueOf方法,它缓存了-128~127的值,超过这个范围(-128~127)就会创建新的实例。

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

@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、由于上面这个特性,所以这种包装类型不能在循环遍历中赋值。不然其值超过这个范围的话,就会创建新的对象,如果很多的话,就会创建很多对象。浪费空间。
}
- 承受的值要注意范围(-2147483648 ~ 2147483647 ),不要求强转。
- 注意valueOf方法,跟Short的方法一样,缓存了-128~127的值,超过这个范围(-128~127)就会创建新的实例。

- 基于第二种情况,不便于进行循环遍历复制操作,否则超过范围就会多个实例,影响内存。
@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、由于上面这个特性,所以这种包装类型不能在循环遍历中赋值。不然其值超过这个范围的话,就会创建新的对象,如果很多的话,就会创建很多对象。浪费空间。
}
- 承受的值要注意范围(-9223372036854775808 ~ 9223372036854775807 ),不要求强转。
- 注意valueOf方法,跟Short的方法一样,缓存了-128~127的值,超过这个范围(-128~127)就会创建新的实例。


- 基于第二种情况,不便于进行循环遍历复制操作,否则超过范围就会多个实例,影响内存。
@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
//由于上面这个特性,所以这种包装类型不能在循环遍历中赋值。不然其值超过这个范围的话,就会创建新的对象,如果很多的话,就会创建很多对象。浪费空间。
}

- 承受的值要注意范围(-1.4E-45~ 3.4028235E38),不要求强转。
- 注意valueOf方法,跟前面的Short、Integer、Long不一样了,直接创建实例。
- 所以相等值的两个变量 ==运算是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
}

- 承受的值要注意范围,不要求强转。
- 注意valueOf方法,与float一样,直接创建实例。


- 不要做加减法运算。精度(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
}

- valueof方法


@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

Java源码解读(一) 8种基本类型对应的封装类型的更多相关文章
- Java源码解读(一)——HashMap
HashMap作为常用的一种数据结构,阅读源码去了解其底层的实现是十分有必要的.在这里也分享自己阅读源码遇到的困难以及自己的思考. HashMap的源码介绍已经有许许多多的博客,这里只记录了一些我看源 ...
- 【Java集合】ArrayDeque源码解读
简介 双端队列是一种特殊的队列,它的两端都可以进出元素,故而得名双端队列. ArrayDeque是一种以循环数组方式实现的双端队列,它是非线程安全的. 它既可以作为队列也可以作为栈. 继承体系 Arr ...
- java.lang.system 类源码解读
通过每块代码进行源码解读,并发现源码使用的技术栈,扩展视野. registerNatives 方法解读 /* register the natives via the static initializ ...
- Java源码阅读的真实体会(一种学习思路)
Java源码阅读的真实体会(一种学习思路) 刚才在论坛不经意间,看到有关源码阅读的帖子.回想自己前几年,阅读源码那种兴奋和成就感(1),不禁又有一种激动. 源码阅读,我觉得最核心有三点:技术基础+强烈 ...
- Java源码阅读的真实体会(一种学习思路)【转】
Java源码阅读的真实体会(一种学习思路) 刚才在论坛不经意间,看到有关源码阅读的帖子.回想自己前几年,阅读源码那种兴奋和成就感(1),不禁又有一种激动. 源码阅读,我觉得最核心有三点:技术基础+ ...
- AFNetworking 3.0 源码解读 总结(干货)(下)
承接上一篇AFNetworking 3.0 源码解读 总结(干货)(上) 21.网络服务类型NSURLRequestNetworkServiceType 示例代码: typedef NS_ENUM(N ...
- AFNetworking 3.0 源码解读(九)之 AFNetworkActivityIndicatorManager
让我们的APP像艺术品一样优雅,开发工程师更像是一名匠人,不仅需要精湛的技艺,而且要有一颗匠心. 前言 AFNetworkActivityIndicatorManager 是对状态栏中网络激活那个小控 ...
- 【Java源码分析】LinkedList类
LinkedList<E> 源码解读 继承AbstractSequentialList<E> 实现List<E>, Deque<E>, Cloneabl ...
- String、StringBuffer、StringBuilder源码解读
序 好长时间没有认真写博客了,过去的一年挺忙的.负责过数据库.线上运维环境.写代码.Code review等等东西挺多. 学习了不少多方面的东西,不过还是需要回归实际.加强内功,方能扛鼎. 去年学习M ...
随机推荐
- Hibernate--使用xml配置映射关系
写在前面: 配置实体类与数据库的映射关系,有两种方式: 1.使用*.hbm.xml 2.使用@注解 二:xml的配置方式: eg:员工的xml配置文件: <?xml version=" ...
- ASP.NET Core MVC请求超时设置解决方案
设置请求超时解决方案 当进行数据导入时,若导入数据比较大时此时在ASP.NET Core MVC会出现502 bad gateway请求超时情况(目前对于版本1.1有效,2.0未知),此时我们需要在项 ...
- ios 去掉字符串中的空格 和指定的字符
[问题分析] .使用NSString中的stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]方法只是去掉左右 ...
- GAME——转圈游戏
我们在生命的路上常常绝望 大概是因为弯路走了太多 脚上的泡被磨起又磨破 像我们所有的幻想与梦 起起落落. 所以说 我这道题考场上面和题解想得一模一样啊啊啊啊啊啊啊啊啊啊!!!!!! 但是就是打复杂了啊 ...
- bzoj 3142: [Hnoi2013]数列
Description 小T最近在学着买股票,他得到内部消息:F公司的股票将会疯涨.股票每天的价格已知是正整数,并且由于客观上的原因,最多只能为N.在疯涨的K天中小T观察到:除第一天外每天的股价都比前 ...
- C#中级-Windows Service程序安装注意事项
一.前言 这周除了改写一些识别算法外,继续我的Socket服务编写.服务器端的Socket服务是以Windows Service的形式运行的. 在我完成Windows Service编写后,启动服务时 ...
- split 命令详解
作用:将大文件切割成小文件. 参数:-l 按照行数分隔文件 -b 按照大小分隔文件 -d 使用数字做后缀 实例:分隔文件默认1000行 split mylog ; wc ...
- 一、 kettle开发、上线常见问题以及防错规范步骤
此篇说明对应的kettle版本是6.1,实际使用时7.x应该也是一样的. 一. kettle开发流程(规范步骤,防止出错) (一) Kettle设置检查 资源库连接 如果不加一下配置 ...
- MySQL字符串相关函数学习一
这里总结一下常用的或者有可能用到的一些字符串内建函数 ① ASCII() :返回字符的ASCII码 如果输入的不是一个字符而是一个字符串呢?ascii()会只取第一个字符作为计算的参数,如: ② CH ...
- iOS学习——UI相关小结
1 StoryBoard: 在Info.plist中可以查看Main storyboard,即入口storyboard,默认为main.storyboard,可以修改为自己创建的storybo ...