public class A{
   A a = null;
}
//这里为什么可以这样定义A a= null;都还没有A类型,内存中还有没A的数据结构吧
这个问题我问个几次,但每次都不是很理解
知道的同仁麻烦从编译器或JVM方面简单说下

解决方案 »

  1.   

    分配了类A的地址空间
    与是不是null无关系吧
      

  2.   

    应楼主之要求,反编译
    public class A{ 
      A a = null; 
    }
    后的输出结果:
    Compiled from "A.java"
    public class A extends java.lang.Object{
    A a;public A();
      Code:
       0:   aload_0
       1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
       4:   aload_0
       5:   aconst_null
       6:   putfield        #2; //Field a:LA;
       9:   return}Compiled from "A.java"
    public class A extends java.lang.Object{
    A a;public A();
      Code:
       0:   aload_0
       1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
       4:   aload_0
       5:   aconst_null
       6:   putfield        #2; //Field a:LA;
       9:   return}
      

  3.   


    Compiled from "A.java"
    public class A extends java.lang.Object{
    A a;public A();
      Code:
       0:   aload_0
       1:   invokespecial   #1; //Method java/lang/Object."<init>":()V //调用object里的方法
       4:   aload_0   //这是什么意思
       5:   aconst_null
       6:   putfield        #2; //Field a:LA;  //看不出来有什么
       9:   return}
      

  4.   

    分配了类A的地址空间 与null无关系吧
      

  5.   

    public class A{ 
      A a = null; 
    }
    这只是一个数据结构的定义
    你不调用 new A(),对内存没有任何影响。
    当你调用 new A()的时候,JVM先在堆里面创建一个对象,里面有一个对象指针字段(就是 A a),不过里面的值是空的,表示是null的。
    因此你把这个A a当成一个指针好了,JVM知道的是它是一个指向A类型对象的指针而已如果有如下代码,比如:
    public class A{ 
      A a = null; 
      public static void main(String args[]){
        A xx=new A();
        xx.a=new A();
      }
    }
    指向main方法时,JVM在堆里面创建了2个对象
    第1个对象的成员a因为第二句,指向了第2个对象,
    而第2对象的成员a还是空的,没有指向任何对象。
      

  6.   

    这样用的时候,还没有A的数据结构,为什么可以定义A类型的a变量(A a = null)
    只有到加载时,内存里有A的数据结构!在此这前,根本不知道A是什么东西,怎么可以用来定义变量a
      

  7.   

    public class A{
      A a = null;

    加载这个类的时候首先看到的就是A,里面怎么会不知道A是个什么东西呢,A是什么根本不重要。先明确自己想了解到到底是什么问题,编译器负责编译的事 ,jvm负责加载和执行的问题。
      

  8.   

    public class A{ 
      A a = null; 
    }
    中A a = null; 其实是首先在栈中分配了a单元,此时内容为空;
    假如 public class A{ 
      A a = null; 
      a=new A();
    }则a=new A();在堆中分配了一个单元,然后a是指向了堆中的单元的地址。A a = null;的作用是初始化,方便作为成员变量调用。
      

  9.   


    在加载A的时候,就遇到了A a = null,但些A的数据结构还不完整啊( 比如在A a后还有其它的变量),JVM此时怎么处理
      

  10.   

    到jvm处理的时候A肯定是完整的了。不完整class的验证都通不过。
    你考虑的问题是编译器的问题,不是jvm的问题。
      

  11.   

    是我想晕了,谢谢ZangXt ,还有hbwhwang 
    也给hbwhwang 50分
      

  12.   

    编译器对代码进行分析的时候,遇到public class A会把A加入到符号表中,后面再用到A,符号表里已经有这项了,所以能找到。
      

  13.   

    接楼上的: 编译器负责编译的事 ,jvm负责加载和执行的事
    编译的时候由编译器全权负责,我认为编译器把A作为了一种类型存入类型符号表中,在编译到a的时候他会到能用的类型符号表中寻找前面的A类型,一个lookup函数查找,而这个A在类型符号表中的属性就不管了,他可以赋予哪些值也不管了,反正就有null值。我觉得这阶段就是类型检查,编译器完成他的任务但些A的数据结构还不完整啊( 比如在A a后还有其它的变量),JVM此时怎么处理:JVM只管有.class文件就能可以把其加载入内存,即只要不存在编译时错误(静态检查过程)的问题,执行就从main开始,A a = null;定义了一个对象的引用,用到不用到就不知道了