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 了 ;


  • 相关阅读:
    NYOJ 10 skiing DFS+DP
    51nod 1270 数组的最大代价
    HDU 4635 Strongly connected
    HDU 4612 Warm up
    POJ 3177 Redundant Paths
    HDU 1629 迷宫城堡
    uva 796
    uva 315
    POJ 3180 The Cow Prom
    POJ 1236 Network of Schools
  • 原文地址:https://www.cnblogs.com/young-youth/p/11665742.html
Copyright © 2011-2022 走看看