присваивание переменной класса, объявленной в методе без создания объекта - PullRequest
1 голос
/ 04 мая 2019

Пример - класс Card с методом swap (). Два объекта Card создаются. Метод меняет их, объявляя третью переменную Card, но не создавая экземпляр третьего объекта. Третья переменная используется в качестве временного держателя для поддержки обмена. Я ожидал, что своп не сработает, потому что переменная temp ссылается на первый объект, затем первому объекту назначается второй объект, а второму объекту назначается temp, который, согласно моим предположениям, фиксирует изменение для первого объекта. .

public class Tester
{
   public static void main(String[] args)
   {
      Card[] cards = new Card[2];
      cards[0] = new Card('x');
      cards[1] = new Card('y');

      System.out.println( cards[0].getVal() + "\n" + cards[1].getVal() + "\n" );

      Card.swap(cards);

      System.out.println( cards[0].getVal() + "\n" + cards[1].getVal() + "\n" );
   }
}

//Card class --------------------------------------------------------------------
class Card
{   

   private char value;


   public Card(char value)
   { 
      set(value);
   }

   public static void swap(Card[] cards){
      Card temp = cards[0];
      cards[0] = cards[1];
      cards[1] = temp;
   }


   public boolean set(char value)
   {

      this.value = value;
      return true;
   }


   public char getVal()
   {
      return value;
   }
}

Выход:

х
у

у
х

Я ожидаю, что карты [0] и карты [1] будут ссылаться на память, на которую ссылались карты [1], до того, как temp будет назначен картам [1]. Я ожидаю, что разыменование карт [0] будет потеряно.

Фактический результат состоит в том, что карты [0] меняются местами с картами [1]. (Является ли это истинной копией или переключателем ссылок?) Насколько я понимаю, поскольку все переменные Java являются ссылками, разыменование temp станет карточкой [1], когда разыскивание карточек [0] станет карточками [1]. Теперь похоже, что у temp есть собственная память, хотя ей не был назначен объект кучи в «новой» операции. В другом месте я читал кое-что, что подсказывало мне, что именно так работают переменные метода, но я не мог найти ничего, что подтвердило бы, что именно так работают переменные метода пользовательского типа или любого не примитивного типа.

Ответы [ 2 ]

1 голос
/ 04 мая 2019

Ссылка в контексте Java не похожа на ссылки в C или C ++. В Java вы скорее имеете дело с указателями, и эти указатели передаются по значению.

Таким образом, также отсутствует автоматическое копирование объектов (что вы и предполагали), и после вашего обмена остается только два Card объекта, которые вы создали до вызова метода.

Ответы и комментарии на вопрос Является ли Java «передачей по ссылке» или «передачей по значению»? может помочь понять это.

1 голос
/ 04 мая 2019
  Card temp = cards[0];
  cards[0] = cards[1];
  cards[1] = temp;

Ссылка на объект карты 'X (удерживаемая позицией 0 массива) присваивается переменной' temp '.

Затем ссылка на объект карты Y (удерживается1 позиция массива) присваивается 0 позиции массива.

Затем ссылка на объект 'card X' (удерживаемая переменной 'temp') назначается 1 позиции массива.

Позже, когда вы разыменовываете ссылку, которую массив держит в своей позиции 0, вы получаете «карту Y», как и ожидалось.

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