Локальные глобальные переменные VS в Java
Я думал, что понимаю разницу между локальными и глобальными переменными в Java, пока не увидел пример сегодня. В этом коде каждый пытается добавить элементы в список ссылок в методе:
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;
}
}
заранее спасибо
2 ответа
Это смешивание переменных и объектов, newElement
действительно локальная переменная, и она теряется после завершения метода, но ссылка указывает на объект. Объект пригоден для сборки мусора, если на него нет ссылок (переменных). В этом случае временно newElement
а также firstElement
оба указали на это. Потерял newElement
когда метод вышел, но firstElement
по-прежнему указывает на это, как и lastElement
так что он не подходит для сбора мусора.
Или другими словами: переменная относится к объекту, это не сам объект.
Аналогия:
- переменная: лист бумаги, на котором вы можете написать адрес
- объект: дом
- сборщик мусора: снос экипажа
Я строю дом и пишу его адрес на клочке бумаги, чтобы вы могли туда добраться, я передаю вам этот клочок бумаги, вы записываете адрес с клочка бумаги в адресную книгу, вы выбрасываете клочок бумаги.
Команда по сносу проверяет, пользуется ли кто-нибудь еще домом, проверяя, сохранил ли кто-нибудь его адрес. Даже если вы выбросили клочок бумаги, у вас все еще есть адрес в адресной книге, поэтому дом все еще используется и не разрушен.
newElement
это просто ссылка на объект, созданный в памяти.
firstElement
затем содержит ссылку на тот же объект.
Ссылка newElement
действительно является локальной переменной, но объект, на который ссылается ссылка, затем также упоминается с помощью другой ссылки, т.е. firstElement
, Так что после addDataPacket()
метод завершается, newElement
ссылка больше не существует, но объект, на который она ссылается, все еще существует в памяти, и на этот объект ссылается firstElement
,