博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
课程作业06:验证课件上的代码,并将所有的动手动脑或要求发表博客作业部分整理成一篇博客发表。...
阅读量:4363 次
发布时间:2019-06-07

本文共 2566 字,大约阅读时间需要 8 分钟。

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

 

验证结论:如果类提供了一个自定义的构造方法,将导致系统不再提供默认的构造方法。所以此时需要无参的构造方法时,需要自己写一个空的构造方法,即系统默认的构造方法。

 

2. 如果一个类中既有初始化块,又有构造方法,同时还设定了字段的初始值,谁说了算?

 

 

请依据代码的输出结果,自行总结Java字段初始化的规律。

 

规律一:类字段的初始化顺序

1.执行类成员定义时指定的默认值或类的初始化块,到底执行哪一个要看哪一个“排在前面”,输出结果是排在后边的那个,先执行的被修改为后执行的。

2.执行类的构造函数。

规律二:类初始化块的应用

类的初始化块不接收任何的参数,而且只要一创建类的对象,它们就会被执行。因此,适合于封装那些“对象创建时必须执行的代码”。

 

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

package give3;

 

public class TestStaticInitializeBlock {

 

    public static void main(String[] args) {

       new Leaf();

       }

}

 

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的构造器");

    }

}

结果截图:

 

静态初始化的执行顺序:

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

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

 

4.静态方法中只允许访问静态数据,那么,如何在静态方法中访问类的实例成员(即没有附加static关键字的字段或方法)?请编写代码验证你的想法。

 

类的静态成员(变量和方法)属于类本身,在类加载的时候就会分配内存,可以通过类名直接去访问;非静态成员(变量和方法)属于类的对象,所以只有在类的对象产生(创建类的实例)时才会分配内存,然后通过类的对象(实例)去访问。

 

5. 两对整数明明完全一样,为何一个输出true,一个输出false?

 

输出结果表明i1和i2指向的是同一个对象,而i3和i4指向的是不同的对象。此时只需一看源码便知究竟,下面这段代码是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() {}

    }

 

从这2段代码可以看出,在通过valueOf方法创建Integer对象的时候,如果数值在[-128,127]之间,便返回指向IntegerCache.cache中已经存在的对象的引用;否则创建一个新的Integer对象。上面的代码中i1和i2的数值为100,因此会直接从cache中取已经存在的对象,所以i1和i2指向的是同一个对象,而i3和i4则是分别指向不同的对象。

 

转载于:https://www.cnblogs.com/iCheny/p/7700615.html

你可能感兴趣的文章
cogs1885 [WC2006]水管局长数据加强版
查看>>
paramiko模块
查看>>
[原创]茗洋AaronYang的 jquery.myselect.js 我的一次前端突破[上]
查看>>
1083 是否存在相等的差
查看>>
Redis总结(四)Redis 的持久化(转载)
查看>>
About_Return
查看>>
10.24给TA的话
查看>>
数组_leetcode209
查看>>
日系插画学习笔记(三):光影与结构
查看>>
C语言——几道习题
查看>>
CentOS——自己安装网卡驱动
查看>>
工具系列 | VScode Remote 远程开发与调试(告别SSH)
查看>>
Django QuestSet API (官方文档)
查看>>
2018 Multi-University Training Contest 10
查看>>
ArcGIS JavaScript API4.8 底图选择的几种方案
查看>>
Linux 后台执行命令
查看>>
多线程学习笔记
查看>>
C# 队列集合的使用
查看>>
POJ 2947 Widget Factory (高斯消元 判多解 无解 和解集 模7情况)
查看>>
PC-LINT
查看>>