2015-08-21 17 views
2

考虑下面的代码片段的类:JVM如何装载有它自己的参考

public class ListNode 
{ 
    ListNode nextNode; 

    //Constructors follow ... 

    //Member methods follow ... 
} 

我不知道很多关于类加载的内部,对我来说,它看起来像装(因为类永远不能创建)将永远不会完成,因为ListNode将继续尝试查找ListNode类,不是吗?

然而,这是许多数据结构的基本原理中的一个(链表例如)。它很明显,它的作品。

所以,JVM如何解释这样一个类定义,什么是技术术语叫做这种提法?

+0

这就是'递归'并将你带入'stackoverflow' –

+2

@sᴜʀᴇsʜᴀᴛᴛᴀ错误... – immibis

+0

@immibis Yah。仅仅这种说法是错误的。我用我的答案详细解释。 –

回答

2

类本身只装载一次。你可能会错误地把课堂当作对象。但即使是对象,由于引用是空的(你只是声明了变量,但没有分配任何东西),所以没有问题。

1

要记住的要点

1)术语本身就是错误的,你需要来看,它的类的实例。

2)如果您正在考虑自己的类实例化,技术术语是recursion,并在某段时间后遇到stackoverlow错误。

3)你的代码

public class ListNode 
    { 
     ListNode nextNode; 

     //Constructors follow ... 

     //Member methods follow ... 
    } 

是不会造成任何堆栈溢出,因为你没有实例,只是宣布它。

4)下面的代码

public class ListNode 
    { 
     ListNode nextNode = new ListNode(); 

     //Constructors follow ... 

     //Member methods follow ... 
    } 

是因为它本身实例计算器。

1

您的类定义只包含字段声明类型为类本身。它不会尝试创建该类的实例。这不会造成问题,因为在初始化类时,字段的类型甚至不能解析。例如,您的字段甚至可能是运行时未知的类型,但您不会得到NoClassDefFoundError。通过规范,你会得到错误只有当你真正试图通过实例化,垂头丧气进去指型,请致电签名与它的方法等

2

这是可能实现你的建议是什么,但这听起来并不容易。一个类只能在一个线程中初始化,并且在完成之前它不能被另一个线程访问。

public class Main { 
    static class Deadlock { 
     static int NUM = 1; 

     static { 
      Thread t = new Thread(new Runnable() { 
       @Override 
       public void run() { 
        // tries to use NUM in a new thread 
        System.out.println(NUM); 
       } 
      }); 
      t.start(); 
      try { 
       t.join(); 
      } catch (InterruptedException e) { 
       throw new AssertionError(e); 
      } 
     } 
    } 

    public static void main(String[] args) { 
     System.out.println("About to dead lock"); 
     new Deadlock(); 
     System.out.println(".. never gets here"); 

    } 
} 

,如果你把一个堆栈跟踪您看到

"Thread-0" #11 prio=5 os_prio=0 tid=0x00007f9c2414a800 nid=0x2188 in Object.wait() [0x00007f9be983b000] 
    java.lang.Thread.State: RUNNABLE 
    at Main$Deadlock$1.run(Main.java:14) 
    at java.lang.Thread.run(Thread.java:745) 

"main" #1 prio=5 os_prio=0 tid=0x00007f9c2400a000 nid=0x2163 in Object.wait() [0x00007f9c2caf0000] 
    java.lang.Thread.State: WAITING (on object monitor) 
    at java.lang.Object.wait(Native Method) 
    - waiting on <0x00000000fec64ec0> (a java.lang.Thread) 
    at java.lang.Thread.join(Thread.java:1245) 
    - locked <0x00000000fec64ec0> (a java.lang.Thread) 
    at java.lang.Thread.join(Thread.java:1319) 
    at Main$Deadlock.<clinit>(Main.java:19) 
    at Main.main(Main.java:28) 

主线程等待后台线程完成,但它不能得到NUM的值,因为班里有没有完成初始化。