课后作业——2022.10.02

1.动手动脑1

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

 

原因:

首先,当类没有定义构造函数时,会自动生成一个无参的构造方法,但当类中定义了构造方法时,就会覆盖自动生成的构造方法,

这是只能使用类中定义的构造函数,题中类已经构造一个有参的构造方法,需要参数才能调用,而主函数中只能调用类中的构造

方法,但调用没有参数,导致匹配错误,所以会产生错误。

2.动手动脑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();
        

    }
}

输出结果:

 

总结:

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

2)执行子类的对象时,会先执行父类的静态初始化块的

3.动手动脑3

问题:神奇代码(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;//false

        Integer j2=129;

        System.out.println(i2==j2);

    }


}

输出结果:

 

原因:

因为它们调用的Interger类的方法不同,所以结果不同

下面这段代码是Integer的valueOf方法的具体实现:
public static Integer valueOf(int i) {
        if(i >= -128 && i <= IntegerCache.high)
            return IntegerCache.cache[i + 128];
        else
            return new Integer(i);
    }
而其中IntegerCache类的实现为:
 private static class IntegerCache {
        static final int high;
        static final Integer cache[];

        static {
            final int low = -128;

            // high value may be configured by property
            int h = 127;
            if (integerCacheHighPropValue != null) {
                // Use Long.decode here to avoid invoking methods that
                // require Integer's autoboxing cache to be initialized
                int i = Long.decode(integerCacheHighPropValue).intValue();
                i = Math.max(i, 127);
                // Maximum array size is Integer.MAX_VALUE
                h = Math.min(i, Integer.MAX_VALUE - -low);
            }
            high = h;

            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);
        }

        private IntegerCache() {}
    }
从代码可以看出,在通过valueOf方法创建Integer对象的时候,如果数值在[-128,127]之间,
便返回指向IntegerCache.cache中已经存在的对象;否则创建一个新的Integer对象。
100会直接从cache中取已经存在的对象,所以指向的是同一个对象,而后者则是分别指向不同的对象。

posted @ 2022-10-02 16:57  sodamate  阅读(24)  评论(0编辑  收藏  举报