自从读了《thinking  in java 》后,小生对 自学的 java  总有些 疑问(这不知是好是坏)。构造器的加载顺序中的某些细节还是 不太理解!!第一问: 加载类时,有基类,则以基类的对象为优先加载,至于同类 其他成员,先查看static 变量,再到static 方法。对吗?而下代码 有这情况:先  private String s;再到static的 构造方法。所以我很乱了。
第二问:到底 基类成员加载 顺序 如何?共两问!!(明白意思 。建议 代码 不要看  否则 会晕!! )
import com.bruceeckel.simpletest.*;class Characteristic {
  private String s;
  Characteristic(String s) {
    this.s = s;
    System.out.println("Creating Characteristic " + s);
  }
  protected void dispose() {
    System.out.println("finalizing Characteristic " + s);
  }
}class Description {
  private String s;
  Description(String s) {
    this.s = s;
    System.out.println("Creating Description " + s);
  }
  protected void dispose() {
    System.out.println("finalizing Description " + s);
  }
}class LivingCreature {
  private Characteristic p = new Characteristic("is alive");
  private Description t =
    new Description("Basic Living Creature");
  LivingCreature() {
    System.out.println("LivingCreature()");
  }
  protected void dispose() {
    System.out.println("LivingCreature dispose");
    t.dispose();
    p.dispose();
  }
}class Animal extends LivingCreature {
  private Characteristic p= new Characteristic("has heart");
  private Description t =
    new Description("Animal not Vegetable");
  Animal() {
    System.out.println("Animal()");
  }
  protected void dispose() {
    System.out.println("Animal dispose");
    t.dispose();
    p.dispose();
    super.dispose();
  }
}class Amphibian extends Animal {
  private Characteristic p =
    new Characteristic("can live in water");
  private Description t =
    new Description("Both water and land");
  Amphibian() {
    System.out.println("Amphibian()");
  }
  protected void dispose() {
    System.out.println("Amphibian dispose");
    t.dispose();
    p.dispose();
    super.dispose();
  }
}public class Frog extends Amphibian {
  private static Test monitor = new Test();
  private Characteristic p = new Characteristic("Croaks");
  private Description t = new Description("Eats Bugs");
  public Frog() {
    System.out.println("Frog()");
  }
  protected void dispose() {
    System.out.println("Frog dispose");
    t.dispose();
    p.dispose();
    super.dispose();
  }
  public static void main(String[] args) {
    Frog frog = new Frog();
    System.out.println("Bye!");
    frog.dispose();
    monitor.expect(new String[] {
      "Creating Characteristic is alive",
      "Creating Description Basic Living Creature",
      "LivingCreature()",
      "Creating Characteristic has heart",
      "Creating Description Animal not Vegetable",
      "Animal()",
      "Creating Characteristic can live in water",
      "Creating Description Both water and land",
      "Amphibian()",
      "Creating Characteristic Croaks",
      "Creating Description Eats Bugs",
      "Frog()",
      "Bye!",
      "Frog dispose",
      "finalizing Description Eats Bugs",
      "finalizing Characteristic Croaks",
      "Amphibian dispose",
      "finalizing Description Both water and land",
      "finalizing Characteristic can live in water",
      "Animal dispose",
      "finalizing Description Animal not Vegetable",
      "finalizing Characteristic has heart",
      "LivingCreature dispose",
      "finalizing Description Basic Living Creature",
      "finalizing Characteristic is alive"
    });
  }
} ///:~

解决方案 »

  1.   

    第一问: 加载类时,有基类,则以基类的对象为优先加载,至于同类 其他成员,先查看static 变量,再到static 方法。对吗?而下代码 有这情况:先 private String s;再到static的 构造方法。所以我很乱了。
    第二问:到底 基类成员加载 顺序 如何?共两问!!
    ---------------
    第一问:
    加载方法,从上到下,肯定先基类,后子类。对于静态成员,是按照从代码的顺序加载的,即从第一行到静态方法的后面开始加载的,并不是说先 静态成员,再静态方法,没有这种说法,有代码验证如下:
    static {
    i = 2;
    }
    private static int i = 3; public static void main(String[] args) {
    System.out.println(T3.i);
    }这段代码,打印出T3.i,结果为3,而并不是2,就是因为加载顺序从前面到后面,如果方法在前面,就加载前面的方法,变量在前面,就加载前面的变量。第二问:
    由于静态和普通成员不一样,所以 加载顺序也不一样,首先,静态代码块和静态成员是先于普通成员先加载的,因为静态代码在类初始化时就加载了,等所有的静态代码加载完之后,再加载普通成员。而且,静态代码加载一次之后,就不再加载了。
    对于普通成员,与静态成员的加载顺序不同,它首先必须完全加载完所有的成员,才后进入到构造方法。但对于内部代码块,类似 {}这种的非静态代码块, 它的加载顺序和静态代码块一样的,都是从前面到后面,如下代码可证明: {
    i = 2;
    }
    private int i = 3; public static void main(String[] args) {
    T3 t = new T3();
    System.out.println(t.i);
    }
    此时,输出i为3所以加载顺序为 父级静态成员-子类静态成员-父类普通成员及构造函数-子类普通成员及构造函数
      

  2.   

    我刚出来混呢~,问细节问题,其实不是在转牛角尖的。因为之前学c#时  ,这懂一点哪懂一点,学习效果很差。后来,发誓  这学年的  java ,一定不能像一盘“散沙”所以 希望 能学成一个体系。师兄 !你说的: 加载顺序为 父级静态成员-子类静态成员-父类普通成员及构造函数-子类普通成员及构造函数。  我很高兴地说句 :啦啦我学到一些实用的知识了~~
    不过~! 我对静态成员加载顺序 提出一个疑问class astatic{
    public static int iii() {
            a= 2;          //(虽然 静态 方法之前 ,a 还没有 创建。但是 正确)
            return 4;
        }
    public astatic(){
    System.out.println(a);
    }

    public static int b=a;   //(有误。因为 b 之前 ,a 还没 创建)
    public static int a=0;
     
    }有误地方说明  显式声明 静态的成员  加载顺序 有从上而下的 特征, 标明正确的地方 说明 除了纵向特征还有横向特征  那就是 先 变量 后 方法。以 你的经验,这结论 有木有 错?