03-类与方法

一、如果一个类中既有初始化块,又有构造方法,同时还设定了字段的初始值,谁说了算?以下代码输出结果是什么?

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

执行结果:

当“public int field=100;”在“{field=200;}”之前时,field初始化数值是由“{field=200;}”说了算;当“public int field=100;”在“{field=200;}”之后时,field初始化数值是由“public int field=100;”说了算。也就是说,那句话在后边,后执行,则哪句话说了算。

注:类字段的初始化顺序

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

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

 

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

代码:

 1 package shiyan3;
 2 class InitializeBlockClass {
 3     {
 4         field=200;
 5     }
 6     public int field=100;
 7     public InitializeBlockClass(int value)
 8     {
 9         this.field=value;
10     }
11     
12     public InitializeBlockClass()
13     {
14         
15     }
16 
17     public static void main(String[] args) {
18         // TODO Auto-generated method stub
19         InitializeBlockClass obj=new InitializeBlockClass();
20         System.out.println(obj.field);
21         
22         obj=new InitializeBlockClass(300);
23         System.out.println(obj.field);
24     }
25 }

执行结果:

静态初始化块的执行顺序:

(1)  先执行静态初始化块,再执行普通方法。静态初始化块只执行一次。

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

 

三、一个有趣的问题

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

请编写代码验证你的想法。

 1 package shiyan3;
 2 public class Example
 3  {
 4   static int  x = 1;//类的静态变量,初始化值为4
 5   int y = 2;        //类的实例变量,初始化值为3
 6   public static void method()//静态方法
 7    {  
 8       System.out.println("静态变量x = " + x);//在静态方法中可直接访问类的静态变量
 9       System.out.println("实例变量y = " + new Example().y);//在静态方法中访问类的实例变量需首先进行类的实例化
10    }
11  
12   public static void main(String[] args) 
13      {
14           Example.method();
15           Example xm = new Example();
16           System.out.println("y = " + xm.y);
17      }
18  }

四、神奇代码

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

提示:

   使用javap来分析生成class文件,看它调用了Interger类的哪个方法,然后打开JDK源文件查看源码,就可以找到答案。

Integer=100; 实际上调用的是Integer.valueOf(int i);
因为从-127到128之间的Integer数,Java在Integer中有事先缓存好的原型对象,每次返回的都是同一个Integer对象,只有不在这个范围的数才会新创建出一个Integer,最后所指都不是同一个对象,所以比较的不是同一个对象。

 

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

设计思想:

每次执行分为3个选择:1-创建对象,2-查询已创建对象个数,3-退出。

若选择1,之后要输入创建的对象个数,以对象数组的形式创建,程序循环,每次创建的对象数依次累加。

若选择2,可随时查询已经创建的对象个数。

若选择3,可随时退出。

代码:

 1 package shiyan3;
 2 //信1605-2 20163588 王金萱
 3 import java.util.Scanner;
 4 public class countDuixiang {
 5     public static void main(String[] args)
 6     {
 7         Duixiang oo=new Duixiang();
 8         oo.f();
 9     }
10 }
11 class Duixiang
12 {
13     static int n;
14     static int count;
15     public Duixiang()
16     {
17         count=n;
18     }
19     public void f()
20     {
21         int j=0;
22         Scanner in=new Scanner(System.in);
23         do
24         {
25             System.out.println("1-创建对象  2-查询已创建对象个数 3-退出");
26             j=in.nextInt();
27             if(j==1)
28             {
29                 System.out.print("请输入要创建的对象个数:");
30                 int m=in.nextInt();
31                 Duixiang d[]=new Duixiang[m];
32                 n+=m;
33                 Duixiang w3=new Duixiang();
34                 System.out.println("创建成功!");
35             }
36             if(j==2)
37             {
38                 System.out.println("你已经创建了"+Duixiang.count+"个对象");
39             }
40         }while(j!=3);
41     }
42 }

执行结果:

 

posted @ 2017-10-20 00:13  顾北清歌寒。  阅读(189)  评论(0编辑  收藏  举报