Java中的本地VS全局变量

Hos*_*Tav 2 java variables global local

在我今天看到一个例子之前,我以为我理解了java中局部和全局变量之间的区别.在此代码中,我们尝试将元素添加到方法中的链接列表中:

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

我不明白为什么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;
}
Run Code Online (Sandbox Code Playgroud)

}

先感谢您

Wes*_*Wes 8

在此输入图像描述newElement 只是对在内存中创建的对象的引用.

firstElement 然后保存对同一对象的引用.

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


Ric*_*gle 6

这是混合变量对象,newElement确实是一个局部变量,它在方法结束后丢失,但引用指向一个对象.如果没有引用(变量)指向它,则对象可以进行垃圾收集.在这种情况下暂时newElement并且firstElement都指向它.newElement当方法退出时它会丢失,但firstElement仍然指向它,因为lastElement它不能用于垃圾收集.

或者换句话说:变量是指对象,而不是对象本身.

一个类比:

  • 变量:你可以写一个地址的纸
  • 对象:房子
  • 垃圾收集器:强拆船员

我盖了一幢房子并在一张纸上写下了地址,这样你就可以到达那里,我把那张纸扔给你,你把那张纸上的地址写进了你的地址簿,然后扔掉了那张纸.

拆迁人员通过查看是否仍有人持有其地址来检查是否有人仍在使用房屋.即使你扔掉了那张纸,你仍然在你的地址簿里有地址,所以房子仍在使用,而且没有被拆除