Вопрос о передаче по ссылке (адресу памяти) в Java - PullRequest
0 голосов
/ 27 ноября 2018

У меня есть простой класс IntList, у которого есть метод iterativeSize ().

public class IntList {
    public int first;
    public IntList rest;

    public IntList(int f, IntList r) {
        this.first = f;
        this.rest = r;
    }

    public static void main(String[] args) {
        IntList L = new IntList(15, null);
        L = new IntList(10, L);
        L = new IntList(5, L);


        L.iterativeSize();
        System.out.println(L.first) // this gives 5 instead of null
    }

 public int iterativeSize() {
        IntList x = this;
        int count = 0;

        while (x != null) {
            count++;
            x = x.rest;
        }

        return count;
    }

Как я и предполагал, исходный L должен стать нулевым из-за цикла while, который завершается только тогда, когда x == null.Поскольку x имеет адрес памяти L, L должен был стать нулевым после:

L.iterativeSize ();

Но это не так.Почему L не изменяется, хотя x (который имеет адрес памяти L) стал нулевым?

Ответы [ 3 ]

0 голосов
/ 27 ноября 2018

IntList L; и IntList x = this; - это не одна и та же переменная , даже если они содержат одно и то же значение (ссылка на один и тот же экземпляр IntList) в одной точке.Таким образом, когда x становится нулевым, это не влияет на L.

List<String> list1ref1 = new ArrayList<>(); // <-- only one instance created
List<String> list1ref2 = list1ref1; // <-- second reference to same instance

// both variables reference the same instance of the object
// thus they both 'add' to the same instance
list1ref1.add("1");
list1ref2.add("2");

System.out.println(list1ref1); // [1, 2]
System.out.println(list1ref2); // [1, 2]

// 'list1ref2' now does not reference any instance, aka null
list1ref2 = null;

// but `list1ref1` still references that original instance
System.out.println(list1ref1); // [1, 2]
System.out.println(list1ref2); // null
0 голосов
/ 27 ноября 2018

Вы используете x в качестве указателя для перехода по различным экземплярам IntList, но это не меняет значение L. Во-первых: L и x находятся в разных областях.Вы можете изменить только значение L внутри метода main, так как его область действия есть.Второе: чтобы изменить значение L, вам нужна команда явного распределения значений, например, L = что-то.

0 голосов
/ 27 ноября 2018

this - указатель на экземпляр IntList.Вы копируете этот указатель в переменную x и изменяете только этот указатель, а не данные.И вы не изменяете L в основной программе, поэтому он остается неизменным, указывая на неизмененные данные.Вы должны написать L = L.rest в вашей функции main , если хотите что-то уничтожить.

...