Java源码分析(二)Double

2023-09-17 20:54:35

    本篇是源码分析的第二篇,上篇我们一起分析了Integer类的源码,本篇一起学习下Double类的源码,看下其实现。

一、Double类图

    首先,相比Integer,Double类的源码只有1000+行代码。如下是Integer及其关联类/接口的类图:

     通过Integer类的类图,我们总结下它的特点:

  • Double类继承自抽象类Number
  • Double类实现了Comparable接口
  • Double类使用final修饰,因此不可以有子类(不能被继承)

二、String转Double

    同Integer类似,在实际工作中,我们用的比较多的,仍然是String转Double。Java也是给我们提供了两个方法:

1、Double.parseDouble

    public static double parseDouble(String s) throws NumberFormatException {
        return FloatingDecimal.parseDouble(s);
    }

    可以看到,parseDouble并非在Double类中实现的,而是借助FloatingDecimal类去实现:

    public static double parseDouble(String s) throws NumberFormatException {
        return readJavaFormatString(s).doubleValue();
    }

    readJavaFormatString方法返回ASCIIToBinaryConverter:

static ASCIIToBinaryConverter readJavaFormatString( String in ) throws NumberFormatException {...}

    而ASCIIToBinaryConverter接口有两个方法,分别是doubleValue()和floatValue(),显而易见,分别是转double和转float的方法:

   interface ASCIIToBinaryConverter {

        double doubleValue();

        float floatValue();

    }

2、Double.valueOf

    另一种方法是Double.valueOf,需要注意的是,valueOf每次都是new一个Double,也就是一个新的对象。

    public static Double valueOf(String s) throws NumberFormatException {
        return new Double(parseDouble(s));
    }

    为什么Double不像Integer搞个缓存呢?浮点数不像整型,比如1和2之间就有无数个浮点数,那么又如何去实现类似IntegerCache的缓存呢?显然是不现实的! 

三、isNaN

    需要注意的一点,Double内部定义了一个非法的double值,即NaN:

    /**
     * A constant holding a Not-a-Number (NaN) value of type
     * {@code double}. It is equivalent to the value returned by
     * {@code Double.longBitsToDouble(0x7ff8000000000000L)}.
     */
    public static final double NaN = 0.0d / 0.0;

     相应的,在很多情况下,确实会产生NaN的double值,因此在使用一个double值做一些运算时,记得使用Double.isNaN去判断下该非法值并做相应的异常处理:

    /**
     * Returns {@code true} if the specified number is a
     * Not-a-Number (NaN) value, {@code false} otherwise.
     *
     * @param   v   the value to be tested.
     * @return  {@code true} if the value of the argument is NaN;
     *          {@code false} otherwise.
     */
    public static boolean isNaN(double v) {
        return (v != v);
    }

    如下代码示例:

    public static void main(String[] args) {
        String s = "NaN";
        double d = 0d;
        try {
            d = Double.parseDouble(s);
        } catch (NumberFormatException e) {
            System.out.println(e.getMessage());
            return;
        }
        if (Double.isNaN(d)) {
            System.out.println(d);
            return;
        }
        d = d * 2.0d;
        System.out.println(d);
    }

四、一道题目

    那么,看下这道题目输出是什么呢?

public class DoubleTest {
    public static void main(String[] args) {
        Double d1 = 100d;
        Double d2 = 100d;
        System.out.println(d1 == d2);
    }
}

    答案是false。原因则是上面提到的,valueOf每次都是new一个Double对象。 

    相比Integer的源码,Double源码相对简单一些。但是需要特别注意使用double时isNaN的判断,否则程序可能产生意想不到的错误。

更多推荐

【每日一题Day333】LC2603收集树中金币 | 拓扑排序

收集树中金币【LC2603】给你一个n个节点的无向无根树,节点编号从0到n-1。给你整数n和一个长度为n-1的二维整数数组edges,其中edges[i]=[ai,bi]表示树中节点ai和bi之间有一条边。再给你一个长度为n的数组coins,其中coins[i]可能为0也可能为1,1表示节点i处有一个金币。一开始,你需

5.11.Webrtc接口的设计原理

在上节课中呢,我向你介绍了webrtc的接口宏,那有很多同学会产生疑问啊,那觉得webrtc为什么要把接口设计的这么复杂?还非要通过宏来实现一个代理类,再通过代理类来调用到webrtc内部。那为什么要这么设计呢?实际上它的这样一种设计啊,它是有一定理论的,那下面呢,我们就来详细看一下webrtc为什么要这么做?那这张图

Redis——Java客户端配置

概要由于Redis服务器在官网公开了RESP协议,因此第三方可以通过这个协议来实现和Redis服务器通信的客户端程序,而具体的通信逻辑也不需要我们去实现,只需要导入大佬的库即可jedis就是封装了RESP协议,提供了一组api供我们使用导入依赖创建一个maven项目,然后导入下面这个jedis依赖<!--https:/

1.测试 —— 答疑篇

什么是软件测试:软件测试是不是就是找bug?软件测试就是证明软件不存在错误的过程软件测试就是为了证明程序能够正确运行刚新买来一部手机,我们要干什么?一场考试,做完一遍题目之后,进行一遍检查,就是在"测试"买一台电视,安装好之后打开试试看能不能正常使用,也是在"测试"概念:验证软件功能是否满足用户的需求。1979年,Gl

【JavaEE】多线程(一)

多线程(一)文章目录多线程(一)进程操作系统进程PCB属性进程的状态进程的优先级进程的上下文CPU寄存器进程的记账信息虚拟地址空间线程线程与进程的区别Java进行多线程编程在了解多线程之前,我们先聊聊进程进程而了解进程前,我们还需聊聊操作系统~操作系统简单来理解就是搞管理的软件。对下:管理好各种硬件设备对上:要给应用程

什么是HTML5中的Web存储API,包括LocalStorage和SessionStorage?它们的区别是什么?

聚沙成塔·每天进步一点点⭐专栏简介⭐Web存储API和区别⭐LocalStorage(本地存储)⭐SessionStorage(会话存储)⭐区别⭐写在最后⭐专栏简介前端入门之旅:探索Web开发的奇妙世界欢迎来到前端入门之旅!感兴趣的可以订阅本专栏哦!这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的

机器学习——贝叶斯(三种分布)/鸢尾花分类分界图/文本分类应用

0、前言:机器学习中的贝叶斯的理论基础是数学当中的贝叶斯公式。这篇博客强调使用方法,至于理论未作深究。机器学习中三种类型的贝叶斯公式:高斯分布(多分类)、多项式分布(文本分类)、伯努利分布(二分类任务)贝叶斯算法优点:对小规模数据表现好,能处理多分类任务,常用于文本分类。缺点:只能用于分类问题。1、高斯分布的贝叶斯算法

长安汽车:基于云器Lakehouse一体化数据平台,建立智能互联时代的领先优势丨案例研究

长安汽车智能化研究院是中国长安汽车集团有限责任公司旗下专注于汽车智能化技术研究和创新的研发机构。其愿景是通过持续创新和技术突破,实现汽车智能驾驶、智能网联和智能交通的全面发展,提供更安全、更便捷、更智能的出行体验,并成为中国汽车智能化领域的领军企业。智能化是汽车工业发展近百年来对汽车功能的一次重新定义,它旨在利用大数据

利用python工具提取多个word中的图片和表格

1.前言由于工作因素,经常要对多个文档内容进行查重,文字类可以借助查重工具辅助,但图片和表格只能依靠鼠标滚轮还有笔者的打工眼。久而久之,眼睛废了,肩颈也吃不消了(-.-)。于是乎,就想用脚本批量导出,从而提高效率。笔者非软件专业,所以只能请ChatGPT当导师了,经过多次修改,总算达到了预期效果。大佬们如果有更好的办法

基于STM32设计的温室大棚种植监测系统(onenet+GPRS通信)

一、设计简述基于STM32设计的温室大棚种植监测系统(OneNet+GPRS通信)1.1设计需求随着社会经济的快速发展和人们对食品质量安全的日益关注,温室大棚越来越受到人们的青睐。温室大棚可以提供良好的生长环境,使得蔬菜、水果等植物获得更好的生长条件,从而提高产量和质量。然而,在温室大棚内,温度、湿度、二氧化碳含量、光

肖sir___环境的讲解__001

环境的讲解一、搭建环境此测试环境主要用于功能测试、寻找bug、编写后台测试点、熟悉环境的架构,搭建流程二、搭建多有米前后台所需要的工具包1、虚拟机(centos6.5)2、数据库3、代码包4、服务器5、数据库脚本6、jdk三、搭建测试环境实战1、将本地的服务器上传到linux中,并解压tar-zxvf服务器包名2、上传

热文推荐