Java 数组列表中的引用对象

Java 数组列表中的引用对象,java,object,arraylist,reference,Java,Object,Arraylist,Reference,更新问题 你好, 我目前在理解对象在数组列表中是如何引用的,或者更明确地说,如何使用数组列表的get方法真正工作时遇到了一个问题 我将4个对象添加到ArrayList中,然后在“head”指针中存储一个引用 指向第一个插槽中的对象 public List<SmakeSegment> smakeParts = new ArrayList<>(); public SmakeSegment head; public Smake() { addInitialSmak

更新问题

你好,

我目前在理解对象在数组列表中是如何引用的,或者更明确地说,如何使用数组列表的get方法真正工作时遇到了一个问题

我将4个对象添加到ArrayList中,然后在“head”指针中存储一个引用 指向第一个插槽中的对象

public List<SmakeSegment> smakeParts = new ArrayList<>();

public SmakeSegment head;


public Smake() {
    addInitialSmakeSegment(14, 9, RIGHT);
    addInitialSmakeSegment(14, 8, UP);
    addInitialSmakeSegment(15, 8, LEFT);
    addInitialSmakeSegment(15, 9, DOWN);

    state = ALIVE;
    head = smakeParts.get(0);           // TODO: DEBUG check if reference gets updated automatically upon changing list entity
}

private void addInitialSmakeSegment(int i, int i1, int direction) {
    SmakeSegment segment = new SmakeSegment(i * TILESIZE, i1 * TILESIZE, TILESIZE, TILESIZE);
    segment.addTileStep(direction);
    smakeParts.add(segment);
}

public void addSegment(){

    if( smakeParts.size() >= 2 ){

        SmakeSegment original    = smakeParts.get( smakeParts.size() - 2 );
        SmakeSegment duplicate   = new SmakeSegment(  original.getPositionLL().x,
                                                            original.getPositionLL().y,
                                                            TILESIZE, TILESIZE);
        SmakeSegment end         = smakeParts.get( smakeParts.size() - 1 );

        duplicate.setDirection( original.getDirection() );

        smakeParts.remove( smakeParts.size() - 1 );
        smakeParts.add( duplicate );
        smakeParts.add( end );
    }else if(smakeParts.size() ==1){
        SmakeSegment original = smakeParts.get(0);
        SmakeSegment duplicate = new SmakeSegment(original.getPositionLL().x,original.getPositionLL().y,TILESIZE,TILESIZE);
        duplicate.setDirection(original.getDirection());
        smakeParts.add(duplicate);
    }
}
现在真正让我惊奇的是,如果我移除第一个对象:

public void removeSegment(int index){
    if(smakeParts.size() > index && smakeParts.size() > 1) {

        if (!smakeParts.get(index).getPixelMoves().isEmpty()) {
            for (int i = 0; i < smakeParts.get(index).getPixelMoves().size(); i++) {

                if (index + 1 != smakeParts.size())
                    smakeParts.get(index + 1).addStep(smakeParts.get(index).getPixelMoves().get(i));
            }
        }
    }
    smakeParts.remove(index);
}
public void removeSegment(int索引){
if(smakeParts.size()>index&&smakeParts.size()>1){
如果(!smakeParts.get(index.getPixelMoves().isEmpty()){
对于(int i=0;i
我原以为渲染时会发生错误,因为“head”引用仍然指向旧对象(SmakePart@4206)因此,尽管从列表中删除,但仍将绘制,因为它仍然被引用

但实际情况是,将自动呈现列表中的第一个新对象。调试表明,渲染器中使用的“head”引用仍然保留相同的对象(SmakePart@4206)这怎么可能? 这是吗SmakePart@4206引用我的对象的指针,还是正在引用 ArrayList中的第一个插槽,这就是我在这里看到的,但我想知道如何引用该对象,为什么调试仍然显示旧对象,但在新对象的位置绘制(删除第一个之前的第二个),我的列表也变小了,并且绘制的段少了一段。因此,它实际上按照预期的方式工作,尽管在移除第一个对象时,我从不更新我的“head”引用


感谢您的帮助

以下是一些重要的概念:

  • 对象是使用
    new
  • testling1
    testling2
    是指向对象的引用
  • testling2=testling1
    表示
    testling2
    现在指向
    testling1
    指向的同一对象,但它们仍然是两个不同的引用
  • testling1=null
    表示
    testling1
    不指向任何对象,
    testling2
    不受影响,仍然指向与以前相同的对象
  • 当没有指向对象的引用时,垃圾收集器会自动销毁对象

  • 我认为这应该足以理解代码中发生了什么。

    变量不是对象。
    testling1
    testling2
    都不是“原始对象”;它们都是变量。物体是别的东西。你说物体是别的东西是什么意思?现在好多了
    testling2
    不是对
    testling1
    的引用;它接收相同的值,这是对实例的引用-因此两者都指向同一个实例“因此当我设置testling2=null时对象a将被销毁/删除?”如果将其设置为null(您永远不会这样做),它将有资格进行垃圾收集“对象A B保存在哪里?”在内存中,在堆上“它们的变量存储在哪里?”在内存中,在堆栈上。@RailWander它是对象的成员,作为对象的一部分存储,对象在堆上,因此:是。
    public void removeSegment(int index){
        if(smakeParts.size() > index && smakeParts.size() > 1) {
    
            if (!smakeParts.get(index).getPixelMoves().isEmpty()) {
                for (int i = 0; i < smakeParts.get(index).getPixelMoves().size(); i++) {
    
                    if (index + 1 != smakeParts.size())
                        smakeParts.get(index + 1).addStep(smakeParts.get(index).getPixelMoves().get(i));
                }
            }
        }
        smakeParts.remove(index);
    }