int i = 100;  //对象属性;
 static int j = 200;//类属性,不依赖于创建的对象;
创建对象时,需要new 构造函数,在创建对象时不可能使用要创建对象的属性。比如,你不能吃你明天才能吃到的饭一样。

解决方案 »

  1.   

    要回答这个问题 或许没有表面上那么简单或许得看看 Java虚拟机 之类的或许还得 看看 字节码我只是这么想  我也不知道
      

  2.   

    public class NewClass {    public static void main(String[] args) {
            MyDemo ob = new MyDemo();
        }}class MyDemo extends MyFather {    int i = 100;
        static int j = 200;    public MyDemo() {
            System.out.println("这是MyDemo的无参构造器输出的");
            //super(j); // 这里为什么一定要用 j 不能用 i ,网上说是因为 i 还没有被初始化, 但为什么上面 注释1
            // 的代码执行却可以,Java 的对象初始化究竟是怎样的。
        }}class MyFather {    public MyFather() {
            System.out.println("这是MyDemo的父类MyFather的无参构造函数输出的!");
        }    public MyFather(int i) {
            // TODO Auto-generated constructor stub
        }}运行输出结果是:
        这是MyDemo的父类MyFather的无参构造函数输出的!
        这是MyDemo的无参构造器输出的
    执行流程是这样的:先从入口main处执行,在main里我们实例化了一个MyDemo对象,而MyDemo类是MyFather的子类,所以在实例化MyDemo类时,默认情况下是会执行其父类的无参构造函数的,然后再去执行MyDemo自身的构造器。
    回到问题,因为你在实例化MyDemo时,不管你执行的是MyDemo的有参或是无参构造器,在MyDemo实例化之前先要实例化其父类的构造器,i 成员属性是需要实例化之后才能用的,而 j 是类属性,属性自身类的,无须实例化就能用。
      

  3.   

    静态属性在类初始化的时候已经被初始化完成.属性肯定是在super()方法结束之后再被初始化.
      

  4.   

    为什么    public MyDemo() { System.out.println(i);}     能顾运行呢?class MyDemo extends MyFather {
      int i;
      static int j;  public MyDemo();
        Code:
           0: aload_0       
           1: invokespecial #1                  // Method MyFather."<init>":()V    没有调用super 
           4: aload_0       
           5: bipush        100                // 将100 保存到 i
           7: putfield      #2                    // Field i:I        // 关键点在这里  Print 之前 已经替你做好初始化了
          10: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
          13: aload_0       
          14: getfield      #2                  // Field i:I
          17: invokevirtual #4                  // Method java/io/PrintStream.println:(I)V
          20: return        
        LineNumberTable:
          line 13: 0
          line 10: 4
          line 13: 10  static {};
        Code:
           0: sipush        200
           3: putstatic     #5                  // Field j:I
           6: return        
        LineNumberTable:
          line 11: 0
    }
      

  5.   

    为什么 super(i) 不能起作用呢?(而且会有编译错误)public class java {
     
        public static void main(String[] args) {
            MyDemo ob = new MyDemo();
        }
    }
     
    class MyDemo extends MyFather {
        int i = 100;
        static int j = 200;
         
        public MyDemo() {
            super(); 
        }
    }
     
    class MyFather {
        public MyFather() {
        }
        public MyFather(int i) {
        }
    }
    Compiled from "java.java"class MyDemo extends MyFather {
      int i;  static int j;  public MyDemo();
        Code:
           0: aload_0       
           1: invokespecial #1                  // Method MyFather."<init>":()V    关键点在这里  1. 先调用了super 
           4: aload_0       
           5: bipush        100
           7: putfield      #2                  // Field i:I                                                                          2. 再初始化 i 的。 所以 i 是null 或默认值
          10: return                              // 其实 应该是可以用null 或 默认值 调用Super的吧(我想C++或许可以)
        LineNumberTable:                // 或许Java是为了安全和健壮才不让这么做的 
          line 16: 0
          line 10: 4
          line 18: 10  static {};
        Code:
           0: sipush        200
           3: putstatic     #3                  // Field j:I
           6: return        
        LineNumberTable:
          line 11: 0
    }
      

  6.   

    创建对象的时候分为2个步骤,第一步是为对象的实例变量分配内存,第二步才是为这些变量初始化(也就是执行构造器部分)
    当你创建MyDemo的对象ob的时候:
    第一步,JVM会先为对象的实例变量i分配内存空间并给默认值,int的默认值就是0,于是此时i为0
    第二步,为变量初始化,这个时候则会先依次调用父类的非静态初始化块和构造器部分(分显式和隐式),然后才是调用本类的非静态初始化块和构造器,当然你这里用的显式调用(也就是你super(j)这一句)
    所以如果你调用super(i)的话,其实i已经被分配了内存空间,值为0
    但是会报编译错误,可能是因为此时i必然是默认值,编译器认为没有意义?
      

  7.   

    子类初始化之前,会先去初始化父类。所以先调用super(),但这时int i=100;还没被初始化,所以就报错了。但静态变量不同,静态变量不依附类本身的创建。