假设有两个类
class Father
{
   static int int_father;
   String str_father = getStr();
   String getStr()
   {
      int_father++;
      System.out.println("Father.getStr()");
      return " ";
   }
   Father()
   {
      System.out.println("Father.constructor");
      System.out.println("Father.int_father="+int_father);
   }
}
class Son extends Father
{
   static int int_son;
   String str_son = getStr();
   String getStr()
   {
      int_son++;
      System.out.println("Son.getStr()");
      return " ";
   }
   Son()
   {
      System.out.println("Son.constructor");
      System.out.println("Son.int_son="+int_son);
   }
}
    当用new Son()时结果如下:
Son.getStr()
Father.constructor
Father.int_father=0
Son.getStr()
Son.constructor
Son.int_son=2
    而在两个类中的String getStr()前面加个static关键字,再运行就变成
Father.getStr()
Father.constructor
Father.int_father=1
Son.getStr()
Son.constructor
Son.int_son=1
    这是怎么回事? 
    像这样的问题有人说有什么实际意义,我说不上来,大家觉得呢?

解决方案 »

  1.   

    怎么说呢?这其实是一个非常基础的问题。只需了解Java的类及其成员、构造函数的执行顺序,以及一些多态的知识就能回答这个问题了。首先,当你用new实例化一个类时,会依次执行下面的操作:
    1. 如果类还未加载的话,则加载类,并依次初始化static变量。
    2. 依次初始化实例变量(非static变量)。
    3. 调用构造函数,并返回对象的reference。如果该类继承自另一个类,则先对其父类执行上述操作。
    比如:Son继承自Father,而Father继承自Object,那么执行new Son()的时候,先对Object执行上述操作,接下来是Father,最后是Son。然后就是多态了。
    Son中的getStr()方法覆盖了Father中的同名方法,这样就构成了运行时多态。也就是说,任何时候调用getStr()方法,都是根据其对象的运行时类型(Runtime Type)来调用的。于是,就可以解释第一种情况下的结果了:执行new Son()时,首先加载父类,并初始化父类的静态变量int_father为0。接下来,初始化父类的实例变量str_father,这需要用到getStr()方法,而getStr()又是一个多态方法,这使得子类的getStr()方法被调用,从而将子类的静态变量int_son变为1(自增操作),并打印出字符串“Son.getStr()”。再接着,调用父类的构造函数,打印出“Father.constructor”和“Father.int_father=0”,因为Father中的int_father变量并没有被自增,所以仍然是0。下面对子类执行同样的操作,而这时因为int_son已经是1了,当再执行getStr()时,int_son又被自增一次而变成2。第二种情况(getStr()方法为static的情况)就很好解释了,其实仅仅是因为static方法不构成多态,因而每次执行它时都只影响自身类。最后,我认为这绝不可能是“全世界所有程序员都会犯的错误”,相反,应该是每个Java程序员都应该掌握的基础知识。
      

  2.   

    请Dan1980() 看看
    http://community.csdn.net/Expert/topic/4896/4896851.xml?temp=.5551569
      

  3.   

    我们用java解决实际问题。欢迎有经验的java程序员加入我们的讨论,因人数接近上限,初级人员暂时不能加入,请谅解。QQ 群:3001581