zoukankan      html  css  js  c++  java
  • 向前引用 ? float VS long ? 这些知识你懂吗?

    thinking in java 读书笔记(感悟);
    
    作者:淮左白衣 ;
    
    写于 2018年4月2日18:14:15
    

    目录


    基本数据类型

    我们常说的基本数据类型是有8种的,但是在thinking in java 里面把void也当做基本数据类型了 ;
    
    基本数据类型 大小 最小值 最大值 包装器类型
    boolean ——(没有明确指定) —— —— Boolean
    char 16 - bit unicode 0 unicode 2161 Character
    byte 8 - bit -128 127 Byte
    short 16 - bit 215 2151 Short
    int 32 - bit 231 2311 Integer
    long 64 - bit 263 2631 Long
    float 32 - bit 1.4E45 3.4028235E38 Float
    double 64 - bit 4.9E324 1.7976931348623157E308 Double
    void —— —— —— Void

    我们可以看到对于boolean类型,是没有明确指定其大小的;仅仅定义为够取其字面值 truefalse


    float 和 long 谁更大

    我们都知道 float 是 32 位,long 是 64位 ;因此,我们可能会脱口而出,当然 64位的 long 更大了 ;

    很好,全错了 ;float 更大 ;

    现在我讲下,为什么 float 比 long 大

    这需要从 long 和 float 在内存中的保存方式说起;对比于float,long 在内存中占64位,每一位可以表示 0 或 1,因此最大有 263

    而我们的float ,在内存中并不是向 long 那样存储的,也就是说它不是,把每一个二进制位上的数字连在一起,最后转为十进来表示最后的数值的 ;它在内存中的存储方式如下图:

    • float 内存存储图
    二 ~ 九 十 ~ 三十二
    S(符号位) E(指数域) F(小数域)

    这8位指数域,配合上系数,秒杀掉long 的 263 ,是绰绰有余的 ;


    System.out.println();

    用了这么久的,你真的了解System.out.println();吗?
    
    • System

      System是 java.lang 包下的一个类;

    • out

      out,是System的一个静态成员对象;类型是PrintStream ;

    • println()

      是out对象的一个方法 ;


    向前引用

    java消除了向前引用 ;书上,就说了这么一句 ;本着刨根问底的精神,我来讲什么是向前引用 ;

    • 什么是向前引用

      向前、引用 ,分开看;就是在一个变量定义之前,引用它 ;这在C++等一些语言中,是不可行的 ;java消除了向前引用的错误,意味着,在java中,这样做是可行的 ;

        {
            j = 7; // ok
        }
        int j = 9 ;
    
        {
            i = 9 ;  // error,不能再同一个代码块中使用向前引用
            int i = 6 ;
        }

    这样的代码是正确的,即使 j 定义在后面 ;(备注:向前引用,不能在 同一个 局部代码块中使用;)但是向前引用,仅限于赋值,也就是我们在向前引用的时候,只能对变量进行赋值,不能进行其他操作 ;

    • 为什么向前引用,不能发生在同一个代码块里面

      其实这里也就说出了,为什么java可以向前引用;java能向前引用的可行之处,在于,java加载类的时候的顺序 ;
      我们这里不讲具体的加载顺序,我会在后面专门写一篇博客讲; 这里我们需要知道:在一个类加载的时候,类的字段成员是最先加载的,然后才是代码块,最后是方法

        {
            j = 7; // ok
        }
        int j = 9 ;

    这就是为啥 j = 7 ;是OK的原因;其实在执行代码块的时候,j 已经加载进内存,完成默认初始化了 ;

        {
            i = 9 ;  // error,不能再同一个代码块中使用向前引用
            int i = 6 ;
        }

    当在同一个代码里面的时候,java也是要按照顺序进行加载的,i = 9 ; 这时候 i 还并未加载,因此报错 ;

    • 向前引用的一些注意事项
     class test {  
             int method() {return n; }  
             int m = method();  
             int n = 1;  
    
        } 
    
    // Junit测试
    
        {
            System.out.println(new test().m);
            System.out.println(new test().method());
        }
    // 分别输出:0 , 1  ;
    • 为什么会这样,m的值为什么不是 1?

      这就需要从对象的初始化说起了;

      当我们创建一个对象的时候,首先会把类的字段成员,按顺序加载进内存,然后,把这些字段成员放进一张表(符号表)里面,以便向前引用,这些字段成员在符号表里面的值,是默认初始化的,比如上面的m、n,它们在这张表里面的值都是默认初始化的值 0 ;

      当所有的字段成员,都加载进符号表里面,然后才开始真正的初始化,也就是程序员为它们赋予的值,比如上面的 m = method()、n = 1

      OK,知道上面的知识,就好理解m为什么是 0 ,而不是 1 了 ;当创建 test 对象的时候,默认初始化结束后,开始真正的初始化; m = method() : m 的值是方法 method()的返回值,而 method() 返回的是n的值,这时候,n被真正初始化了吗?答案是否定的,因为下一条语句,才是 int n = 1 ;才进行真正的初始化;因此,n的值,只是在符号表中的默认初始化值 0 ;因此,m 的值,就会赋予为 0 了 ;


  • 相关阅读:
    poj 1141 Brackets Sequence (区间DP)
    算法:冒泡排序
    Learning English From Android Source Code:2 Ampersand
    泛泰A870刷4.4专用英文版非触摸CWM Recovery 6.0.4.8(三版通刷)
    Android Studio 那些事|Activity文件前标识图标显示为 j 而是 c
    HDU-4930 Fighting the Landlords 多校训练赛斗地主
    POJ 3211 Washing Clothes(01背包)
    C# winform ListView 的右键菜单的下级菜单的选项视情况禁用方法
    Android系统开发(4)——Autotools
    Android系统开发(3)——Makefile的编写
  • 原文地址:https://www.cnblogs.com/young-youth/p/11665742.html
Copyright © 2011-2022 走看看