• 2019.10.14课堂总结


    一、动手动脑1

     以下代码为何无法通过编译?哪儿出错了?

            该段代码定义了Foo函数,但没有给Foo函数提供参数,Java编译器不会提供默认构造方法而是使用以定义的方法。

    二、动手动脑2

    请运行TestStaticInitializeBlock.java示例,观察输出结果,总结出“静态初始化块的执行顺序”。

    代码如下:

    class Root {
        static {
            System.out.println("Root的静态初始化块");
        }
        {
            System.out.println("Root的普通初始化块");
        }
    
        public Root() {
            System.out.println("Root的无参数的构造器");
        }
    }
    
    class Mid extends Root {
        static {
            System.out.println("Mid的静态初始化块");
        }
        {
            System.out.println("Mid的普通初始化块");
        }
    
        public Mid() {
            System.out.println("Mid的无参数的构造器");
        }
    
        public Mid(String msg) {
            // 通过this调用同一类中重载的构造器
            this();
            System.out.println("Mid的带参数构造器,其参数值:" + msg);
        }
    }
    
    class Leaf extends Mid {
        static {
            System.out.println("Leaf的静态初始化块");
        }
        {
            System.out.println("Leaf的普通初始化块");
        }
    
        public Leaf() {
            // 通过super调用父类中有一个字符串参数的构造器
            super("Java初始化顺序演示");
            System.out.println("执行Leaf的构造器");
        }
    
    }
    
    public class TestStaticInitializeBlock {
        public static void main(String[] args) {
            new Leaf();
    
        }
    }
    View Code

    运行结果截图:

     总结如下:

    1、静态初始化块只执行一次。

    2、创建子类型的对象时,也会导致父类型的静态初始化块的执行。

    三、进行试验1

    使用上页幻灯片中定义的类,以下代码输出结果是什么?请依据代码的输出结果,自行总结Java字段初始化的规律。

                 

    运行结果截图:

    总结:

    1、执行类成员定义时指定的默认值或类的初始化块,到底执行哪一个要看哪一个“排在前面”。

    2、当有构造函数时执行类的构造函数。

    四、有趣的问题

    静态方法中只允许访问静态数据,那么,如何在静态方法中访问类的实例成员(即没有附加static关键字的字段或方法)?

     验证代码如下:

    public class fangwen {
        public static void fun(fangwen s) {
            s.fun1();
        }
    
        public void fun1() {
            System.out.println("访问成功");
        }
    
        public static void main(String[] args) {
            fangwen s1 = new fangwen();
            fun(s1);
        }
    }
    View Code

     五、Integer的“诡异”特性

     神奇代码(StrangeIntegerBehavior.java)输出诡异的结果,原因何在?

    代码如下:

    public class StrangeIntegerBehavior {
    
        public static void main(String[] args) {
    
            Integer i1 = 100;
    
            Integer j1 = 100;
    
            System.out.println(i1 == j1);
    
            Integer i2 = 129;
    
            Integer j2 = 129;
    
            System.out.println(i2 == j2);
    
        }
    
    }
    View Code

    结果如下:

     使用javap来分析生成class文件,看它调用了Interger类的哪个方法

     然后打开JDK源文件查看源码

    /**
         * Cache to support the object identity semantics of autoboxing for values between
         * -128 and 127 (inclusive) as required by JLS.
         *
         * The cache is initialized on first usage.  The size of the cache
         * may be controlled by the {@code -XX:AutoBoxCacheMax=<size>} option.
         * During VM initialization, java.lang.Integer.IntegerCache.high property
         * may be set and saved in the private system properties in the
         * sun.misc.VM class.
         */
    
        private static class IntegerCache {
            static final int low = -128;
            static final int high;
            static final Integer cache[];
    
            static {
                // high value may be configured by property
                int h = 127;
                String integerCacheHighPropValue =
                    sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
                if (integerCacheHighPropValue != null) {
                    try {
                        int i = parseInt(integerCacheHighPropValue);
                        i = Math.max(i, 127);
                        // Maximum array size is Integer.MAX_VALUE
                        h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
                    } catch( NumberFormatException nfe) {
                        // If the property cannot be parsed into an int, ignore it.
                    }
                }
                high = h;
    
                cache = new Integer[(high - low) + 1];
                int j = low;
                for(int k = 0; k < cache.length; k++)
                    cache[k] = new Integer(j++);
    
                // range [-128, 127] must be interned (JLS7 5.1.7)
                assert IntegerCache.high >= 127;
            }

    六、课后作业

    使用类的静态字段和构造函数,可以跟踪某个类所创建对象的个数。请写一个类,在任何时候都可以向它查询“你已经创建了多少个对象?”

     代码如下:

    package HomeTest;
    
    public class Objnumber {
        private static int sum=0;
        public Objnumber() {
            sum++;
        }
        public static void num() {
            System.out.println("你已经创建了"+sum+"个对象");
        }
        public static void main(String[] args) {
            Objnumber obj = new Objnumber();
            Objnumber.num();
        }
    }
    View Code

  • 相关阅读:
    linux中服务器定时程序设定
    Linux中java项目环境部署,简单记录一下
    四则运算使用栈和后缀表达式
    PAT乙1003
    L7,too late
    PAT乙1002
    L6,Percy Buttons
    如何计算递归算法的时间复杂度
    c#打印(转)
    C中数组与指针【转】
  • 原文地址:https://www.cnblogs.com/best-hym/p/11681204.html
Copyright © 2020-2023  润新知