Yang

课后动手动脑问题解决(2019-10-14)

一、动手动脑1

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

2、原因

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

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

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

 

二、动手动脑2

1、题目:

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

 1 class Root
 2 {
 3     static{
 4         System.out.println("Root的静态初始化块");
 5     }
 6     {
 7         System.out.println("Root的普通初始化块");
 8     }
 9     public Root()
10     {
11         System.out.println("Root的无参数的构造器");
12     }
13 }
14 class Mid extends Root
15 {
16     static{
17         System.out.println("Mid的静态初始化块");
18     }
19     {
20         System.out.println("Mid的普通初始化块");
21     }
22     public Mid()
23     {
24         System.out.println("Mid的无参数的构造器");
25     }
26     public Mid(String msg)
27     {
28         //通过this调用同一类中重载的构造器
29         this();
30         System.out.println("Mid的带参数构造器,其参数值:" + msg);
31     }
32 }
33 class Leaf extends Mid
34 {
35     static{
36         System.out.println("Leaf的静态初始化块");
37     }
38     {
39         System.out.println("Leaf的普通初始化块");
40     }    
41     public Leaf()
42     {
43         //通过super调用父类中有一个字符串参数的构造器
44         super("Java初始化顺序演示");
45         System.out.println("执行Leaf的构造器");
46     }
47 
48 }
49 
50 public class TestStaticInitializeBlock
51 {
52     public static void main(String[] args) 
53     {
54         new Leaf();
55         
56 
57     }
58 }

输出结果:

 

 

2、原因:

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

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

 

三、动手动脑3

1、题目:

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

2、代码如下

 1 public class Objectnum {
 2     private static int sum=0;
 3     public Objectnum() {
 4         sum++;
 5     }
 6     public static void num() {
 7         System.out.println("目前已创建"+sum+"个对象");
 8     }
 9     public static void main(String[] args) {
10         Objectnum obj = new Objectnum();
11         Objectnum obj1 = new Objectnum();
12         Objectnum obj2 = new Objectnum();
13         Objectnum.num();
14     }
15 }

 

3、输出如下

 

 

四、动手动脑4

1、题目

 

 上页ppt如下:

 

 2、输出结果

 

 

3、总结分析

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

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

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

 

五、动手动脑5

1、题目

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

2、代码

 1 public class staticplay {
 2     public static void play(staticplay s1) {
 3         System.out.println("你在静态方法中");
 4         s1.play1();
 5         System.out.println("你在静态方法中");
 6     }
 7   public void play1() {
 8       System.out.println("这是动态方法");
 9   }
10   public static void main(String[] args) {
11       staticplay s=new staticplay();
12       play(s);
13 }
14 }

3、运行结果

 

 

六、动手动脑6

1、问题

以下代码输出诡异的结果,原因何在?

2、代码

 1 public class StrangeIntegerBehavior 
 2 {
 3 
 4     
 5     public static void main(String[] args)
 6     {
 7 
 8         
 9         Integer i1=100;
10        
11         Integer j1=100;
12         
13         
14         System.out.println(i1==j1);
15 
16         
17         Integer i2=129;//false
18         
19         Integer j2=129;
20         
21         System.out.println(i2==j2);
22     
23     }
24 
25 
26 }

3、输出结果

 

 4、解决

首先用javap来反编译生成class文件,通过源代码进行分析原因

 

 

 

 再打开JDK源文件查看源代码

 1 /**
 2      * Cache to support the object identity semantics of autoboxing for values between
 3      * -128 and 127 (inclusive) as required by JLS.
 4      *
 5      * The cache is initialized on first usage.  The size of the cache
 6      * may be controlled by the {@code -XX:AutoBoxCacheMax=<size>} option.
 7      * During VM initialization, java.lang.Integer.IntegerCache.high property
 8      * may be set and saved in the private system properties in the
 9      * sun.misc.VM class.
10      */
11 
12     private static class IntegerCache {
13         static final int low = -128;
14         static final int high;
15         static final Integer cache[];
16 
17         static {
18             // high value may be configured by property
19             int h = 127;
20             String integerCacheHighPropValue =
21                 sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
22             if (integerCacheHighPropValue != null) {
23                 try {
24                     int i = parseInt(integerCacheHighPropValue);
25                     i = Math.max(i, 127);
26                     // Maximum array size is Integer.MAX_VALUE
27                     h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
28                 } catch( NumberFormatException nfe) {
29                     // If the property cannot be parsed into an int, ignore it.
30                 }
31             }
32             high = h;
33 
34             cache = new Integer[(high - low) + 1];
35             int j = low;
36             for(int k = 0; k < cache.length; k++)
37                 cache[k] = new Integer(j++);
38 
39             // range [-128, 127] must be interned (JLS7 5.1.7)
40             assert IntegerCache.high >= 127;
41         }

原因:由于源代码只支持-128到127的范围,129超出此范围,所以输出如上结果

posted on 2019-10-14 21:07  yangliuliu  阅读(154)  评论(0编辑  收藏  举报

导航