2014-02-18 155 views
2

我以为我明白了Java中局部变量和全局变量之间的差异,直到我今天看到一个例子。在这段代码试图向元素添加到链接列表的方法:Java中的局部VS全局变量

public void addDataPacket(DataPacket data){ 
    PacketQueueElement newElement = new PacketQueueElement(data); 
    if(firstElement != null){ 
     lastElement.setNextElement(newElement); 
     lastElement = newElement; 
    } 
    else{ 
     firstElement = newElement; 
     lastElement = newElement; 
    } 
} 

我不明白的是,为什么为newElement没有方法后消失被关闭?因为这是一个局部变量,并且在任何地方都没有定义。下面是这个类的完整代码:

public class PacketQueue { 

/** Das erste Element in der Warteschlange */ 
private PacketQueueElement firstElement; 

/** Das letzte Element in der Warteschlange. */ 
private PacketQueueElement lastElement; 

/** 
* Instanziert eine neue Warteschlange. 
*/ 
public PacketQueue(){ 
    this.firstElement = null; 
    this.lastElement = null; 
} 

/** 
* Fuegt ein neues Paket ans Ende der Warteschlange an. 
* 
* @param data Das neue Paket 
*/ 
public void addDataPacket(DataPacket data){ 
    PacketQueueElement newElement = new PacketQueueElement(data); 
    if(firstElement != null){ 
     lastElement.setNextElement(newElement); 
     lastElement = newElement; 
    } 
    else{ 
     firstElement = newElement; 
     lastElement = newElement; 
    } 
} 

/** 
* Entfernt das erste Element der Warteschlange und gibt es zurueck. 
* 
* @return Das erste Element in der Warteschlange 
*/ 
public PacketQueueElement getAndRemoveFirstElement(){ 
    PacketQueueElement element = this.firstElement; 
    this.firstElement = element.getNextElement(); 
    return element; 
} 

/** 
* Gibt das erste Paket aus dem ersten Element zurueck. 
* 
* @return Das erste Paket 
*/ 
public DataPacket getFirstDataPacket(){ 
    return this.firstElement.getData(); 
} 

/** 
* Entfernt das erste Paket der Warteschlange und gibt es zurueck. 
* 
* @return Das erste Paket in der Warteschlange 
*/ 
public DataPacket getAndRemoveFirstDataPacket(){ 
    return this.getAndRemoveFirstElement().getData(); 
} 

/** 
* Gibt das erste Element der Warteschlange zurueck 
* 
* @return Das erste Element 
*/ 
public PacketQueueElement getFirstElement(){ 
    return this.firstElement; 
} 



/** 
* Ueberprueft, ob die Wartschlange leer ist. 
* 
* @return true, wenn sie leer ist 
*/ 
public boolean isEmpty(){ 
    if(firstElement == null){ 
     return true; 
    } 
    else{ 
     return false; 
    } 
} 

/* (non-Javadoc) 
* @see java.lang.Object#toString() 
*/ 
public String toString(){ 
    PacketQueueElement element = this.firstElement; 
    String s = ""; 
    while(element != null){ 
     s += element + "\n"; 
     element = element.getNextElement(); 
    } 
    return s; 
} 

}

预先感谢您

+1

你是什么意思_it不消失_? –

+0

你能指出你在哪里访问newElement,你认为你不应该 –

+0

我的意思是为什么它会被添加到链接列表中作为一个新的元素。因为我认为所有的局部变量在方法关闭后都会被删除 –

回答

4

这是混合了变量对象newElement确实是一个局部变量并且该方法结束后它丢失,但基准点到对象。如果没有引用(变量)指向该对象,则该对象可用于垃圾回收。在这种情况下,临时newElementfirstElement都指向它。当方法退出时丢失了newElement,但firstElement仍然指向它,因为lastElement也是如此,所以它不适合垃圾回收。

换句话说:变量指的是一个对象,它不是对象本身。

打个比方:

  • 变量:一张纸可以在
  • 对象写地址:房子
  • 垃圾收集器:拆除船员

我盖房子和写它是在一张纸上的地址,所以你可以到达那里,我把那张废纸传给你,你从纸上写下地址到你的地址簿中,你扔掉了纸片。

拆除人员通过查看是否有人仍然持有其地址,检查是否有人仍在使用房屋。即使你扔掉了纸片,你仍然有地址簿中的地址,所以房子还在使用中,并没有拆卸

+0

完美的解释。非常感谢 –

8

enter image description herenewElement只是在内存中创建的对象的引用。

firstElement然后持有对同一对象的引用。

参考newElement确实是一个局部变量,但是参考文献所指的对象也被另一个参考文献所引用,即firstElement。因此在addDataPacket()方法完成后,newElement引用不再存在,但它引用的对象仍存在于内存中,并且该对象由firstElement引用。

+0

非常感谢你。很好的解释 –