【Java】JDK源码分析——Double

  • 二.源码分析

    • 1.全局变量

    • 2.构造方法

      • 1)参数为double

      • 2)参数为String

    • 3. parseDouble方法

    • 4. valueOf方法

      • 1)参数为double

      • 2)参数为String

    • 5. isNaN方法

    • 6. isInfinite方法

    • 7. isFinite方法

    • 8. doubleToLongBits方法

      • 1)doubleToRawLongBits方法
    • 9. longBitsToDouble方法

    • 10. toString方法

    • 11. toHexString方法

    • 12. byteValue方法

    • 13. shortValue方法

    • 14. intValue方法

    • 15. longValue方法

    • 16. floatValue方法

    • 17. doubleValue方法

    • 18. hashCode方法

      • 1)hashCode方法
    • 19. equals方法

    • 20. compareTo方法

      • 1)compare方法
    • 21. sum方法

    • 22. max方法

    • 23. min方法

一.概述

======================================================================

Double是double的包装类,用于表示双精度浮点数。

Double的表示方法和int、short、long不同。Double满足IEEE754浮点数表示法。

Double表示的数值占8个字节,共64位。其中0到51位表示尾数部分;52到63位表示指数部分;64位为符号位。

在这里插入图片描述

Double.java中的相关代码:


public final class Double extends Number implements Comparable<Double> {

…

}



**1.Double被final修饰,不能被继承。

2.继承了Number,可以实现数值间的转换。

3.实现了Comparable接口,可以进行Double类型对象之间的比较。**

二.源码分析

========================================================================

1.全局变量


Double.java中的相关代码:


	// 表示正无穷

	// 它的值和Double.longBitsToDouble(0x7ff0000000000000L)计算的结果相同

	public static final double POSITIVE_INFINITY = 1.0 / 0.0;



	// 表示负无穷

	// 它的值和Double.longBitsToDouble(0xfff0000000000000L)计算的结果相同

	public static final double NEGATIVE_INFINITY = -1.0 / 0.0;



	// 表示不是一个数,即一个数不能被表示

	// 它的值和Double.longBitsToDouble(0x7ff8000000000000L)计算的结果相同

	public static final double NaN = 0.0d / 0.0;



	// 表示double所能表示的最大值:1.7976931348623157e+308

	// 它的值和Double.longBitsToDouble(0x7fefffffffffffffL)计算的结果相同

	public static final double MAX_VALUE = 0x1.fffffffffffffP+1023;



	// 表示正常情况下,double可以表示的最小正数:2.2250738585072014E-308

	// 正常情况为小数点前为0x1

	// 它的值和Double.longBitsToDouble(0x0010000000000000L)计算的结果相同

	public static final double MIN_NORMAL = 0x1.0p-1022;



	// 表示double实际上可以表示的最小非零正数:4.9e-324

	// 小数点前为0x0

	// 它的值和Double.longBitsToDouble(0x1L)计算的结果相同

	public static final double MIN_VALUE = 0x0.0000000000001P-1022;



	// double可以表示的最大指数

	public static final int MAX_EXPONENT = 1023;



	// double可以表示的最小指数

	public static final int MIN_EXPONENT = -1022;



	// double占的位数

	public static final int SIZE = 64;



	// 一个double数值占的字节数

	public static final int BYTES = SIZE / Byte.SIZE;



	// 抑制没有类型检查而出现的警告

	@SuppressWarnings("unchecked")

	// Double类中对应的原始的double

	// Double.class和double.class不相等,但Double.TYPE和double.class相等

	public static final Class<Double>   TYPE = (Class<Double>) Class.getPrimitiveClass("double");



	// 用于存储double的数值

	private final double value;



	// 用于序列化

	private static final long serialVersionUID = -9172774392245257468L;





2.构造方法


1)参数为double

Double.java中的相关代码:


	public Double(double value) {

    	// 保存到全局变量

        this.value = value;

	}



2)参数为String

Double.java中的相关代码:


	public Double(String s) throws NumberFormatException {

    	// 调用parseDouble方法,将字符串解析成double型数值

        value = parseDouble(s);

	}



3. parseDouble方法


将字符串解析成double型数值。

Double.java中的相关代码:


	public static double parseDouble(String s) throws NumberFormatException {

    	// 调用FloatingDecimal的parseDouble方法

        return FloatingDecimal.parseDouble(s);

	}



4. valueOf方法


1)参数为double

将double型数值转换为Double对象。

Double.java中的相关代码:


	public static Double valueOf(double d) {

    	// 创建Double对象,对double数值进行封装,返回

        return new Double(d);

	}



2)参数为String

将String对象转换为Double对象。

Double.java中的相关代码:


	public static Double valueOf(String s) throws NumberFormatException {

    	// 调用parseDouble方法,将字符串解析成double型数值

    	// 创建Double对象,对double数值进行封装,返回

        return new Double(parseDouble(s));

	}



5. isNaN方法


判断当前的数是不是数值型的数。

Double.java中的相关代码:


	public boolean isNaN() {

    	// 调用了重载方法

        return isNaN(value);

	}



调用重载的isNaN方法。

判断double型的数是不是数值型的数。

Double.java中的相关代码:


	public static boolean isNaN(double v) {

    	// 每个NaN的存储地址不同

        return (v != v);

	}



6. isInfinite方法


判断当前的数是不是无穷大。

Double.java中的相关代码:


	public boolean isInfinite() {

    	// 调用了重载方法

        return isInfinite(value);

	}



调用了重载的isInfinite方法。

判断double型的数是不是无穷大。

Double.java中的相关代码:


	public static boolean isInfinite(double v) {

    	// 判断是否为正无穷或负无穷

        return (v == POSITIVE_INFINITY) || (v == NEGATIVE_INFINITY);

	}



7. isFinite方法


判断一个double型的数是否有限。

Double.java中的相关代码:


	public static boolean isFinite(double d) {

    	// 对double数取绝对值,判断是否小于等于double能表示的最大值

        return Math.abs(d) <= DoubleConsts.MAX_VALUE;

	}



8. doubleToLongBits方法


将double型的数转换成满足IEEE 754浮点型表示法的long型的数。

**符号位MASK:0x8000000000000000L

指数位MASK:0x7ff0000000000000L

有效位MASK:0x000fffffffffffffL

正无穷:0x7ff0000000000000L

负无穷:0xfff0000000000000L

NaN:0x7ff8000000000000L**

Double.java中的相关代码:


	public static long doubleToLongBits(double value) {

    	// 调用doubleToRawLongBits转换成long型的数

		// 详解在1)处

        long result = doubleToRawLongBits(value);

        // 根据指数位和非零有效位判断是不是NaN

        if ( ((result & DoubleConsts.EXP_BIT_MASK) ==

              DoubleConsts.EXP_BIT_MASK) &&

             (result & DoubleConsts.SIGNIF_BIT_MASK) != 0L)

            // 若是,则设置为NaN

            result = 0x7ff8000000000000L;

        // 返回

        return result;

	}



1)doubleToRawLongBits方法

Double.java中的相关代码:


	public static native long doubleToRawLongBits(double value);



该方法是一个native方法,该方法会将一个double型的数转换成满足IEEE 754浮点型表示法的long型的数,即使该数为NaN,也会进行转换。

9. longBitsToDouble方法


将long型的数按照IEEE 754浮点数标准转换为double型的数。

Double.java中的相关代码:


	public static native double longBitsToDouble(long bits);



该方法是一个native方法。

10. toString方法


将Double对象转换为String对象。

Double.java中的相关代码:


	public String toString() {

    	// 调用了重载方法

        return toString(value);

	}



调用了重载的toString方法。

Double.java中的相关代码:


	public static String toString(double d) {

    	// 调用FloatingDecimal的toJavaFormatString方法

        return FloatingDecimal.toJavaFormatString(d);

	}



11. toHexString方法


将double型的数转换为十六进制的String对象。

Double.java中的相关代码:


    public static String toHexString(double d) {

        // 若该数不是有限的,即超过了double型的最大值或者为NaN

        if (!isFinite(d) )

            // 调用toString方法进行转换

            return Double.toString(d);

        else { // 若该数有限

            // 用来保存转换的十六进制的字符串

            StringBuilder answer = new StringBuilder(24);



            // 若为负数

            if (Math.copySign(1.0, d) == -1.0)

                // 拼接一个负号

                answer.append("-");

            // 拼接16进制的标识符

            answer.append("0x");

            // 求绝对值

            d = Math.abs(d);

            

            // 若数值为0

            if(d == 0.0) {

                // 则拼接“0.0p0”,即0乘以2的0次方,为0

                answer.append("0.0p0");

            } else { // 若不为零

                // 判断数值是否超过了正常的最小正数

                boolean subnormal = (d < DoubleConsts.MIN_NORMAL);



                // 调用doubleToLongBits方法

				// 将其转换成满足IEEE 754浮点型标准的long型数

				// 进行与运算,64到52位变为0

				// 提取51到0位,即有效位(尾数部分)

				// 最后进行或运算,最高位,即64位,置为1

                long signifBits = (Double.doubleToLongBits(d)

                                   & DoubleConsts.SIGNIF_BIT_MASK) |

                    0x1000000000000000L;



                // 若数值小于正常的最小正数

                // 则拼接”0.”,即0x0.

                // 否则,拼接”1.”,即0x1.

                answer.append(subnormal ? "0." : "1.");



                // 调用Long的toHexString方法

				// 将有效位转换为16进制表示的字符串,截取从第三位到第十六位

                // 64位二进制转换位十六进制为16位(0到15)

                // 十六位中,前三位(0,1,2)表示符号位和指数部分

				// 有效位从第四位(3)开始

                String signif = Long.toHexString(signifBits).substring(3,16);

                // 若有效位都是0,则直接拼接一个”0”

                // 若不全为0,则进行正则表达式匹配

                // 从后向前,去掉最少一个最多12个的”0”

                answer.append(signif.equals("0000000000000") ?

                              "0":

                              signif.replaceFirst("0{1,12}$", ""));



                // 拼接p,表示指数中以2为底数

                answer.append('p');

                // 若数值小于正常的最小正数

				// 则指数部分拼接最小指数

				// 否则,调用Math的getExponent方法获取指数,再拼接

                answer.append(subnormal ?

                              DoubleConsts.MIN_EXPONENT:

                              Math.getExponent(d));

            }

            // 获取字符串,返回

            return answer.toString();

        }

	}



12. byteValue方法


获取当前数值对应的byte型数。

Double.java中的相关代码:


	public byte byteValue() {

	    // 进行类型转换,返回

        return (byte)value;

	}



13. shortValue方法


获取当前数值对应的short型数。

Double.java中的相关代码:


	public short shortValue() {

	    // 进行类型转换,返回

        return (short)value;

	}



14. intValue方法


获取当前数值对应的int型数。

Double.java中的相关代码:


    public int intValue() {


**自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。**

**深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!**

**因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。**
![img](https://img-blog.csdnimg.cn/img_convert/7de6c51b4227384f57b7ad9a34e4b0ee.jpeg)
![img](https://img-blog.csdnimg.cn/img_convert/a051e2f0ea8741c880a6d93ec90fff5f.png)
![img](https://img-blog.csdnimg.cn/img_convert/ab0da46380bd6883b15677422edb485c.png)
![img](https://img-blog.csdnimg.cn/img_convert/b23eb45a7f054ac9e7efc71f7a0abd0d.png)
![img](https://img-blog.csdnimg.cn/img_convert/3bda40e7da973fd07fa8a78a58347818.png)
![img](https://img-blog.csdnimg.cn/img_convert/9a4b0caa9fb7500d4f512ed0bb1167a6.png)

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!**

**由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新**

**如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Java)**
![img](https://img-blog.csdnimg.cn/img_convert/c013b178204fc7d984485dd8d4f8a7b6.jpeg)



### 最后

### ActiveMQ消息中间件面试专题

*   什么是ActiveMQ?
*   ActiveMQ服务器宕机怎么办?
*   丢消息怎么办?
*   持久化消息非常慢怎么办?
*   消息的不均匀消费怎么办?
*   死信队列怎么办?
*   ActiveMQ中的消息重发时间间隔和重发次数吗?

**ActiveMQ消息中间件面试专题解析拓展:**

![BAT面试文档:ActiveMQ+redis+Spring+高并发多线程+JVM](https://img-blog.csdnimg.cn/img_convert/94fe6a096d5762ff796e7ca390f55eab.webp?x-oss-process=image/format,png)

* * *

# redis面试专题及答案

*   支持一致性哈希的客户端有哪些?
*   Redis与其他key-value存储有什么不同?
*   Redis的内存占用情况怎么样?
*   都有哪些办法可以降低Redis的内存使用情况呢?
*   查看Redis使用情况及状态信息用什么命令?
*   Redis的内存用完了会发生什么?
*   Redis是单线程的,如何提高多核CPU的利用率?

![BAT面试文档:ActiveMQ+redis+Spring+高并发多线程+JVM](https://img-blog.csdnimg.cn/img_convert/56dceeee02ce4adec25555983e09337f.webp?x-oss-process=image/format,png)

* * *

# **Spring面试专题及答案**

*   谈谈你对 Spring 的理解
*   Spring 有哪些优点?
*   Spring 中的设计模式
*   怎样开启注解装配以及常用注解
*   简单介绍下 Spring bean 的生命周期

**Spring面试答案解析拓展**

![BAT面试文档:ActiveMQ+redis+Spring+高并发多线程+JVM](https://img-blog.csdnimg.cn/img_convert/ae016d4c0cf7881766f458acc2d4b4e3.webp?x-oss-process=image/format,png)

* * *

# 高并发多线程面试专题

*   现在有线程 T1、T2 和 T3。你如何确保 T2 线程在 T1 之后执行,并且 T3 线程在 T2 之后执行?
*   Java 中新的 Lock 接口相对于同步代码块(synchronized block)有什么优势?如果让你实现一个高性能缓存,支持并发读取和单一写入,你如何保证数据完整性。
*   Java 中 wait 和 sleep 方法有什么区别?
*   如何在 Java 中实现一个阻塞队列?
*   如何在 Java 中编写代码解决生产者消费者问题?
*   写一段死锁代码。你在 Java 中如何解决死锁?

**高并发多线程面试解析与拓展**

![BAT面试文档:ActiveMQ+redis+Spring+高并发多线程+JVM](https://img-blog.csdnimg.cn/img_convert/69dc11fb01d20d3e22480c438d974d19.webp?x-oss-process=image/format,png)

* * *

# jvm面试专题与解析

*   JVM 由哪些部分组成?
*   JVM 内存划分?
*   Java 的内存模型?
*   引用的分类?
*   GC什么时候开始?

**JVM面试专题解析与拓展!**

![BAT面试文档:ActiveMQ+redis+Spring+高并发多线程+JVM](https://img-blog.csdnimg.cn/img_convert/e4706ef2ee0ae3f3503dcf5976734186.webp?x-oss-process=image/format,png)



**一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
![img](https://img-blog.csdnimg.cn/img_convert/b6d69fe1814937b8c5922e15ee222738.jpeg)

内存用完了会发生什么?
*   Redis是单线程的,如何提高多核CPU的利用率?

[外链图片转存中...(img-6egJJSi6-1712880200083)]

* * *

# **Spring面试专题及答案**

*   谈谈你对 Spring 的理解
*   Spring 有哪些优点?
*   Spring 中的设计模式
*   怎样开启注解装配以及常用注解
*   简单介绍下 Spring bean 的生命周期

**Spring面试答案解析拓展**

[外链图片转存中...(img-rni7zgz0-1712880200083)]

* * *

# 高并发多线程面试专题

*   现在有线程 T1、T2 和 T3。你如何确保 T2 线程在 T1 之后执行,并且 T3 线程在 T2 之后执行?
*   Java 中新的 Lock 接口相对于同步代码块(synchronized block)有什么优势?如果让你实现一个高性能缓存,支持并发读取和单一写入,你如何保证数据完整性。
*   Java 中 wait 和 sleep 方法有什么区别?
*   如何在 Java 中实现一个阻塞队列?
*   如何在 Java 中编写代码解决生产者消费者问题?
*   写一段死锁代码。你在 Java 中如何解决死锁?

**高并发多线程面试解析与拓展**

[外链图片转存中...(img-yMPmxHis-1712880200083)]

* * *

# jvm面试专题与解析

*   JVM 由哪些部分组成?
*   JVM 内存划分?
*   Java 的内存模型?
*   引用的分类?
*   GC什么时候开始?

**JVM面试专题解析与拓展!**

[外链图片转存中...(img-nG5w2hhj-1712880200083)]



**一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
[外链图片转存中...(img-oYEsbxCe-1712880200084)]

  • 12
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值