Java-метод возвращает копию объекта или ссылку на объект? - PullRequest
0 голосов
/ 25 июня 2019
public class UnderstandingMemoryManagement1 {

  private static boolean flag = false;

  public static void main(String[] args) {

    Set<String> mainNameSet = getNameSet();
    mainNameSet.add("Name-6");

    Log.logInfo(getNameSet() == mainNameSet);
    Log.logInfo(getNameSet().equals(mainNameSet));
    Log.logInfo("------main() END------");
  }
  public static Set<String> getNameSet() {

    Set<String> nameSet = new TreeSet<>();
    nameSet.add("Name-1");
    nameSet.add("Name-2");
    nameSet.add("Name-3");
    nameSet.add("Name-4");

    Set<String> otherSet = nameSet;
    otherSet.add("Name-5");

    if (!flag ) {

      flag = true;
      Log.logInfo(nameSet == otherSet);
      Log.logInfo(nameSet.equals(otherSet));
      Log.logInfo("------getNameSet() END------");
    }
    return nameSet;
  }
}

Когда я запускаю приведенный выше код, почему вывод выглядит как ниже -

INFO: true 
INFO: true 
INFO: ------getNameSet() END------ 
INFO: false 
INFO: false 
INFO: ------main() END------

Почему во второй раз возвращается false, а не true? Насколько я знаю, java копирует ссылку, а не объект.Когда он копирует референс, а не объект, тогда он должен возвращать true и для второго случая.Пожалуйста, объясни мне это.

Ответы [ 2 ]

2 голосов
/ 25 июня 2019

Сначала вы вызываете метод getNameSet() и сохраняете его результат в переменной mainNameSet. Этот метод содержит инструкцию, в которой создается новый экземпляр TreeSet, а затем вы возвращаете этот новый экземпляр:

Set<String> nameSet = new TreeSet<>();
...
return nameSet;

Тогда вы делаете это:

getNameSet() == mainNameSet

Вы снова вызываете getNameSet(), что, в свою очередь, создает новый экземпляр TreeSet и возвращает его. Для каждого getNameSet() вызова у вас есть отдельные TreeSet экземпляры .

Именно поэтому сравнение возвращает false.


Java всегда передается по значению , в случае ссылок это означает, что ссылка, переданная методу, копируется.

void handle(Dog inputDog) {
    inputDog = new Dog("Jack");
}
Dog myDog = new Dog("Fluffy");
handle(myDog);

// The name of the dog referenced by 'myDog' is still Fluffy.
// Upon calling the 'handle' method, a reference to my dog named Fluffy is
// copied to the local reference 'inputDog'. A new dog with the name Jack is
// constructed and stored into the 'inputDog' variable, which is distinct
// from the 'myDog' variable. So 'myDog' doesn't change at all.
2 голосов
/ 25 июня 2019

Метод getNameSet() возвращает ссылку на новый объект TreeSet каждый раз, когда он вызывается. Вы вызываете этот метод три раза в main(), поэтому вы получаете три разных TreeSet объекта.

Сначала false получается из сравнения двух разных объектов TreeSet с оператором ==. Это разные объекты и имеют разные ссылочные значения.

Второй false происходит от mainNameSet.add("Name-6");, который изменяет первый TreeSet, поэтому он больше не равен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...