Как можно сделать назначение Java, чтобы указать на объект вместо того, чтобы сделать копию? - PullRequest
10 голосов
/ 05 мая 2010

В классе у меня есть:

private Foo bar;
public Constructor(Foo bar)
{
    this.bar = bar;
}

Вместо создания копии стержня из объекта, указанного в параметре, возможно ли включить указатель на стержень в конструкторе так, чтобы изменение исходного стержня изменило поле в этом объекте?

Другой способ выразить это:

int x = 7;
int y = x;
x = 9;
System.out.print(y); //Prints 7.

Можно настроить так, чтобы при печати y печаталось 9 вместо 7?

Ответы [ 5 ]

16 голосов
/ 05 мая 2010

Когда переменная используется в качестве аргумента для метода, ее содержимое всегда копируется . (Java имеет only call-by-value .) Здесь важно понимать, что вы можете только ссылаться на объекты через ссылки. Так что на самом деле происходит, когда вы передаете переменную, ссылающуюся на объект, это то, что вы передаете ссылку на объект (по значению!).

Кто-то может сказать вам, что «примитивы передаются по значению» и «не примитивы передаются по ссылке», но это только потому, что переменная никогда не может содержать объект для начала, только ссылку на объект. Когда этот человек это поймет, он согласится, что даже переменные, ссылающиеся на объекты, передаются по значению.

С Является ли Java "передачей по ссылке" или "передачей по значению"?

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

С http://www.javaworld.com/javaworld/javaqa/2000-05/03-qa-0526-pass.html

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

В Java нет противоположной части C ++ «ссылочного типа» для примитивов.

8 голосов
/ 05 мая 2010

Ваш последний пример работает таким образом, потому что int является примитивом, он копируется по значению. В первом примере « this.bar » будет содержать копию ссылки (своего рода указатель) на bar . Поэтому, если вы измените исходную панель (внутренне), это изменение будет отражено в вашем классе. Попробуй.

3 голосов
/ 06 мая 2010

Чтобы получить такое поведение, вы можете изменить член объекта:

public class Number{
  int value;
  Number(int value){
    this.value = value;
  }
  public String toString() {
    return "" + value;
  }
}

Вы можете сделать:

Number x = new Number(7);
Number y = x;
x.value = 9;
System.out.println(y);//prints 9
1 голос
/ 05 мая 2010

Java никогда не копирует объекты. Проще всего думать с точки зрения, что для каждого «нового» у вас будет один экземпляр объекта - никогда больше.

Люди ДЕЙСТВИТЕЛЬНО ЗАПУСКАЮТСЯ, когда обсуждают это с точки зрения передачи по ссылке / передачи по значению, если вы не очень хорошо знакомы с тем, что означают эти термины, я предлагаю вам игнорировать их и просто помнить, что Java никогда не копирует объекты.

Таким образом, java работает точно так, как вы хотели, чтобы ваш первый пример работал, и это является основной частью OO Design - тот факт, что после того, как вы создали экземпляр объекта, это один и тот же объект для всех, кто его использует.

Работа с примитивами и ссылками немного отличается - поскольку они не являются объектами, они всегда копируются - но в итоге Java всегда делает то, что вы хотите, без лишнего синтаксиса или запутанных опций. .

0 голосов
/ 05 мая 2010

Чтобы сохранить первоначальное значение панели элементов, вам необходимо реализовать интерфейс Cloneable. Затем, прежде чем присваивать объекту новое значение, вам необходимо создать его клон, передать клонированное значение и назначить новые значения клонированному объекту. Вот учебник о том, как это сделать http://www.java -tips.org / java-se-tips / java.lang / как реализовать-cloneable-interface.html .

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