Является Java “передачей ссылкой” или “передачей значением”?

Чтобы добавить к этому; Это может произойти, если вы не приложите свой набор данных. Просто потратил полчаса, выяснив это также.

Cheers

6252
задан 21 revs, 17 users 15% 11 July 2018 в 01:31
поделиться

25 ответов

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

Это идет как это:

public static void main(String[] args) {
    Dog aDog = new Dog("Max");
    Dog oldDog = aDog;

    // we pass the object to foo
    foo(aDog);
    // aDog variable is still pointing to the "Max" dog when foo(...) returns
    aDog.getName().equals("Max"); // true
    aDog.getName().equals("Fifi"); // false
    aDog == oldDog; // true
}

public static void foo(Dog d) {
    d.getName().equals("Max"); // true
    // change d inside of foo() to point to a new Dog instance "Fifi"
    d = new Dog("Fifi");
    d.getName().equals("Fifi"); // true
}

В примере выше aDog.getName() все еще возвратится "Max". Значение aDog в main не изменяется в функции foo с Dog "Fifi", когда ссылка на объект передается значением. Если бы это было передано ссылкой, то aDog.getName() в [1 110] возвратился бы "Fifi" после вызова к [1 112].

Аналогично:

public static void main(String[] args) {
    Dog aDog = new Dog("Max");
    Dog oldDog = aDog;

    foo(aDog);
    // when foo(...) returns, the name of the dog has been changed to "Fifi"
    aDog.getName().equals("Fifi"); // true
    // but it is still the same dog:
    aDog == oldDog; // true
}

public static void foo(Dog d) {
    d.getName().equals("Max"); // true
    // this changes the name of d to be "Fifi"
    d.setName("Fifi");
}

В вышеупомянутом примере, Fifi имя собаки после вызова к [1 114], потому что имя объекта было определено в foo(...). Любые операции, который foo работает на [1 117], таковы, что во всех практических целях они выполняются на [1 118], но не возможно изменить значение переменной aDog самой.

5570
ответ дан 29 revs, 26 users 33% 22 November 2019 в 19:37
поделиться

В основном переприсвоение Параметров объекта не влияет на аргумент, например,

private void foo(Object bar) {
    bar = null;
}

public static void main(String[] args) {
    String baz = "Hah!";
    foo(baz);
    System.out.println(baz);
}

распечатает "Hah!" вместо null. Причина это работает, состоит в том, потому что bar копия значения baz, который является просто ссылкой на "Hah!". Если бы это была сама фактическая ссылка, то foo переопределил бы baz к null.

157
ответ дан 2 revs, 2 users 97% 22 November 2019 в 19:37
поделиться

Основная проблема - то, что ссылка Word в выражении "передача ссылкой" означает что-то совершенно другое от обычного значения ссылки Word в Java.

Обычно в ссылке Java означает ссылка на объект . Но технические термины передача ссылкой/значением из теории языка программирования говорит о ссылка на элемент памяти, содержащий переменную , который является чем-то совершенно другим.

111
ответ дан 4 revs, 2 users 89% 22 November 2019 в 19:37
поделиться

Java передает ссылки на объекты значением.

161
ответ дан John Channing 22 November 2019 в 19:37
поделиться

Только для проявления контраста сравните следующий C++ и Java отрывки:

В C++: Примечание: Плохой код - утечки памяти! , Но это демонстрирует точку.

void cppMethod(int val, int &ref, Dog obj, Dog &objRef, Dog *objPtr, Dog *&objPtrRef)
{
    val = 7; // Modifies the copy
    ref = 7; // Modifies the original variable
    obj.SetName("obj"); // Modifies the copy of Dog passed
    objRef.SetName("objRef"); // Modifies the original Dog passed
    objPtr->SetName("objPtr"); // Modifies the original Dog pointed to 
                               // by the copy of the pointer passed.
    objPtr = new Dog("newObjPtr");  // Modifies the copy of the pointer, 
                                   // leaving the original object alone.
    objPtrRef->SetName("objRefPtr"); // Modifies the original Dog pointed to 
                                    // by the original pointer passed. 
    objPtrRef = new Dog("newObjPtrRef"); // Modifies the original pointer passed
}

int main()
{
    int a = 0;
    int b = 0;
    Dog d0 = Dog("d0");
    Dog d1 = Dog("d1");
    Dog *d2 = new Dog("d2");
    Dog *d3 = new Dog("d3");
    cppMethod(a, b, d0, d1, d2, d3);
    // a is still set to 0
    // b is now set to 7
    // d0 still have name "d0"
    // d1 now has name "objRef"
    // d2 now has name "objPtr"
    // d3 now has name "newObjPtrRef"
}

В Java,

public static void javaMethod(int val, Dog objPtr)
{
   val = 7; // Modifies the copy
   objPtr.SetName("objPtr") // Modifies the original Dog pointed to 
                            // by the copy of the pointer passed.
   objPtr = new Dog("newObjPtr");  // Modifies the copy of the pointer, 
                                  // leaving the original object alone.
}

public static void main()
{
    int a = 0;
    Dog d0 = new Dog("d0");
    javaMethod(a, d0);
    // a is still set to 0
    // d0 now has name "objPtr"
}

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

182
ответ дан 4 revs, 4 users 94% 22 November 2019 в 19:37
поделиться

Java передает ссылки значением.

, Таким образом, Вы не можете изменить ссылку, которая передается в.

313
ответ дан ScArcher2 22 November 2019 в 19:37
поделиться

Java всегда является передачей значением, без исключений, когда-либо .

Поэтому как получается, что кто-либо может быть вообще смущен этим и полагать, что Java является передачей ссылкой, или думают, что у них есть пример Java, действующего как передача ссылкой? Ключевой пункт - то, что Java никогда не обеспечивает прямой доступ к значениям сами объекты , в никакой обстоятельства. Единственный доступ к объектам через ссылка к тому объекту. Поскольку объекты Java всегда , получил доступ через ссылку, а не непосредственно, распространено говорить о полях и переменных и аргументы метода как являющийся объекты , когда педантично они - [только 1 110] ссылки на объекты . беспорядок останавливает от этого (строго говоря, неправильный) изменение в номенклатуре.

Так, при вызове метода

  • Для примитивных аргументов (int, long, и т.д.), передача значением фактическое значение из примитива (например, 3).
  • Для объектов, передача значением является значением [1 112] ссылка на объект .

Поэтому, если Вы имеете doSomething(foo) и public void doSomething(Foo foo) { .. }, два Foos скопировали ссылки что точка к тем же объектам.

Естественно, передающий значением ссылка на объект смотрит очень как (и неотличимо на практике от), передача объекта ссылкой.

652
ответ дан 4 revs, 4 users 40% 22 November 2019 в 19:37
поделиться

Я просто заметил, что Вы сослались моя статья .

, Спецификация Java говорит, что все в Java - передача значением. Нет такой вещи как "передача ссылкой" в Java.

ключ к пониманию это - то, что что-то как [1 145]

Dog myDog;

не Собака; это на самом деле указатель Собаке.

то, Что это означает, когда Вы имеете

Dog myDog = new Dog("Rover");
foo(myDog);

, Вы чрезвычайно передающие адрес из созданных Dog объект к foo метод.

(я говорю по существу, потому что указатели Java не являются прямыми адресами, но является самым легким думать о них тот путь)

предположим эти Dog, объект находится в адресе памяти 42. Это означает, что мы передаем 42 методу.

, если Метод был определен как [1 151]

public void foo(Dog someDog) {
    someDog.setName("Max");     // AAA
    someDog = new Dog("Fifi");  // BBB
    someDog.setName("Rowlf");   // CCC
}

, позволяют нам посмотреть на то, что происходит.

  • параметр someDog устанавливается на значение 42
  • в строке "AAA"
    • someDog, сопровождается к Dog, это указывает на (эти Dog объект в адресе 42)
    • , что Dog (тот в адресе 42) попросился изменить его имя на Max
  • в строке "BBB"
    • , новое Dog создается. Скажем, он в адресе 74
    • , мы присваиваем параметр someDog 74
  • в строке "CCC"
    • , someDog сопровождается к Dog, это указывает на (эти Dog объект в адресе 74)
    • , что Dog (тот в адресе 74) попросился изменить его имя на Rowlf
  • тогда, мы возвращаемся

Теперь, давайте думать о том, что происходит вне метода:

Сделал myDog изменение?

существует ключ.

Учет того факта, который myDog указатель , и не фактическое Dog, ответ, НЕТ. myDog все еще имеет значение 42; это все еще указывает на оригинал Dog (но обратите внимание, что из-за строки "AAA", его именем является теперь "Max" - все еще та же Собака; myDog значение не изменилось.)

Это совершенно допустимо к [1 131], следуют адрес и изменяют то, что в конце его; это не заменяет переменную, как бы то ни было.

Java работает точно как C. Можно присвоить указатель, передать указатель на метод, следовать за указателем в методе и изменить данные, на которые указали. Однако Вы не можете измениться, где тот указатель указывает.

В C++, Ada, Паскале и других языках, которые поддерживают передачу ссылкой, можно на самом деле заменить переменную, которая была передана.

, Если бы Java имел семантику передачи ссылкой, foo метод, мы определили выше, изменился бы, где myDog указывал, когда это присвоилось someDog на строке BBB.

Думают о параметрах ссылки, как являющихся псевдонимами для переменной, переданной в. Когда тот псевдоним присвоен, так переменная, которая была передана в.

2939
ответ дан 11 revs, 6 users 73% 22 November 2019 в 19:37
поделиться

Вы никогда не можете передавать ссылкой в Java, и один из путей, который очевиден, - когда Вы хотите возвратить больше чем одно значение из вызова метода. Рассмотрите следующий бит кода в C++:

void getValues(int& arg1, int& arg2) {
    arg1 = 1;
    arg2 = 2;
}
void caller() {
    int x;
    int y;
    getValues(x, y);
    cout << "Result: " << x << " " << y << endl;
}

Иногда Вы хотите использовать тот же шаблон в Java, но Вы не можете; по крайней мере, не непосредственно. Вместо этого Вы могли сделать что-то вроде этого:

void getValues(int[] arg1, int[] arg2) {
    arg1[0] = 1;
    arg2[0] = 2;
}
void caller() {
    int[] x = new int[1];
    int[] y = new int[1];
    getValues(x, y);
    System.out.println("Result: " + x[0] + " " + y[0]);
}

, Как был объяснен в предыдущих ответах, в Java, Вы передаете указатель на массив как значение в getValues. Это достаточно, потому что метод тогда изменяет элемент массива, и условно Вы ожидаете, что элемент 0 будет содержать возвращаемое значение. Очевидно, можно сделать это другими способами, такими как структурирование кода, таким образом, это не необходимо, или построение класса, который может содержать возвращаемое значение или позволить ему быть установленным. Но простой шаблон, доступный Вам в C++ выше, не доступен в Java.

47
ответ дан Jared Oberhaus 22 November 2019 в 19:37
поделиться

Различие, или возможно просто способ, которым я помню, когда я раньше создавался то же впечатление как исходный плакат, является этим: Java всегда является передачей значением. Все объекты (в Java, чем-либо за исключением примитивов) в Java являются ссылками. Эти ссылки передаются значением.

36
ответ дан 2 revs, 2 users 50% 22 November 2019 в 19:37
поделиться

Короче говоря, объекты Java имеют некоторые очень специфические свойства.

В целом, Java имеет типы примитивов (int, bool, char, double, и т.д.), которые передаются непосредственно значением. Тогда Java имеет объекты (все, что происходит от java.lang.Object). Объекты на самом деле всегда обрабатываются через ссылку (ссылка, являющаяся указателем, которого Вы не можете коснуться). Это означает, что в действительности, объекты передаются ссылкой, поскольку ссылки обычно не интересны. Это однако означает, что Вы не можете измениться, на какой объект указывают, когда сама ссылка передается значением.

это звучит странным и сбивающим с толку? Давайте рассмотрим, как передача реализаций C ссылкой и передает значением. В C соглашение по умолчанию является передачей значением. void foo(int x) передачи интервал значением. void foo(int *x) функция, которая не хочет int a, но указатель на интервал: foo(&a). Можно было бы использовать это с & оператор для передачи переменного адреса.

Берут это к C++, и у нас есть ссылки. Ссылки являются в основном (в этом контексте) синтаксическим сахаром, которые скрывают часть указателя уравнения: void foo(int &x) назван [1 111], где сам компилятор знает, что это - ссылка, и адрес нессылки a должен быть передан. В Java все переменные, относящиеся к объектам, на самом деле имеют ссылочный тип, в действительности вызывание вызова по ссылке для большинства предназначает и цели без мелкомодульного управления (и сложность) предоставленный, например, C++.

23
ответ дан 3 revs, 2 users 65% 22 November 2019 в 19:37
поделиться

Я создал поток, посвященный подобным вопросам для любой языки программирования здесь .

Java также упоминается . Вот краткое изложение:

  • Java передает его, параметры значением
  • "значением" являются единственным путем в Java для передачи параметра методу
  • методы использования от объекта, данного, поскольку параметр изменит объект, поскольку ссылки указывают на исходные объекты. (если тот метод сам изменяет некоторые значения)
25
ответ дан 2 revs 22 November 2019 в 19:37
поделиться

Я всегда думаю о нем как о "передаче копией". Это - копия значения быть им примитивный или ссылочный. Если это - примитив, это - копия битов, которые являются значением и если это - Объект, это - копия ссылки.

public class PassByCopy{
    public static void changeName(Dog d){
        d.name = "Fido";
    }
    public static void main(String[] args){
        Dog d = new Dog("Maxx");
        System.out.println("name= "+ d.name);
        changeName(d);
        System.out.println("name= "+ d.name);
    }
}
class Dog{
    public String name;
    public Dog(String s){
        this.name = s;
    }
}

вывод java PassByCopy:

имя = имя Maxx
= Fido

Примитивные классы обертки и Строки неизменны, таким образом, любой пример с помощью тех типов не будет работать то же другими типами/объектами.

29
ответ дан 3 revs, 2 users 71% 22 November 2019 в 19:37
поделиться

Поскольку многие люди упомянули его прежде, , Java всегда является передачей значением

, Вот другой пример, который поможет Вам понять различие ( классический пример подкачки ):

public class Test {
  public static void main(String[] args) {
    Integer a = new Integer(2);
    Integer b = new Integer(3);
    System.out.println("Before: a = " + a + ", b = " + b);
    swap(a,b);
    System.out.println("After: a = " + a + ", b = " + b);
  }

  public static swap(Integer iA, Integer iB) {
    Integer tmp = iA;
    iA = iB;
    iB = tmp;
  }
}

Печать:

Прежде: = 2, b = 3
После: = 2, b = 3

Это происходит, потому что iA и iB являются новыми переменными локальной ссылки, которые имеют то же значение переданных ссылок (они указывают на a и b соответственно). Так, попытка изменить ссылки iA или iB только изменится в локальном объеме а не за пределами этого метода.

35
ответ дан pek 22 November 2019 в 19:37
поделиться

Насколько я знаю, Java только знает вызов по значению. Это означает для примитивных типов данных, Вы будете работать с копией, и для объектов Вы будете работать с копией ссылки на объекты. Однако я думаю, что существуют некоторые ловушки; например, это не будет работать:

public static void swap(StringBuffer s1, StringBuffer s2) {
    StringBuffer temp = s1;
    s1 = s2;
    s2 = temp;
}


public static void main(String[] args) {
    StringBuffer s1 = new StringBuffer("Hello");
    StringBuffer s2 = new StringBuffer("World");
    swap(s1, s2);
    System.out.println(s1);
    System.out.println(s2);
}

Это заполнит Привет Мир и не Мир Привет, потому что в подкачке функционируют, Вы используете копии, которые не оказывают влияния на ссылки в основном. Но если Ваши объекты не неизменны, можно изменить его, например:

public static void appendWorld(StringBuffer s1) {
    s1.append(" World");
}

public static void main(String[] args) {
    StringBuffer s = new StringBuffer("Hello");
    appendWorld(s);
    System.out.println(s);
}

Это заполнит Привет Мир на командной строке. При изменении StringBuffer в Строку, это произведет просто Привет, потому что Строка неизменна. Например:

public static void appendWorld(String s){
    s = s+" World";
}

public static void main(String[] args) {
    String s = new String("Hello");
    appendWorld(s);
    System.out.println(s);
}

Однако Вы могли сделать обертку для Строки как это, которое сделает способным использовать ее со Строками:

class StringWrapper {
    public String value;

    public StringWrapper(String value) {
        this.value = value;
    }
}

public static void appendWorld(StringWrapper s){
    s.value = s.value +" World";
}

public static void main(String[] args) {
    StringWrapper s = new StringWrapper("Hello");
    appendWorld(s);
    System.out.println(s.value);
}

править: я полагаю, что это - также причина использовать StringBuffer когда дело доходит до "добавления" двух Строк, потому что Вы можете modifie исходный объект, какой u не может с неизменными объектами как Строка.

54
ответ дан 4 revs, 2 users 76% 22 November 2019 в 19:37
поделиться

Несколько исправлений к некоторым постам.

C НЕ поддерживает передачу по ссылке. Это ВСЕГДА передается по значению. C++ поддерживает передачу по ссылке, но не по умолчанию и достаточно опасно.

Неважно, какое значение на Java: примитивное или адрес(грубо) объекта, оно ВСЕГДА передается по значению.

Если объект Java "ведет" себя так, как будто передается по ссылке, то это свойство мутируемости и не имеет абсолютно никакого отношения к передаваемым механизмам.

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

.
25
ответ дан 22 November 2019 в 19:37
поделиться

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

7
ответ дан 2 revs, 2 users 50% 22 November 2019 в 19:37
поделиться

Java копирует ссылку по значению. Таким образом, если вы измените ее на что-то другое (например, используя new), то ссылка не изменится вне метода. Для нативных типов она всегда передается по значению.

.
18
ответ дан 22 November 2019 в 19:37
поделиться

Взгляните на этот код. Этот код не будет генерировать NullPointerException ... Он напечатает «Vinay»

public class Main {
    public static void main(String[] args) {
        String temp = "Vinay";
        print(temp);
        System.err.println(temp);
    }

    private static void print(String temp) {
        temp = null;
    }
}

. Если Java передана по ссылке, тогда она должна была сгенерировать NullPointerException , поскольку ссылка установлена ​​на Null.

12
ответ дан 22 November 2019 в 19:37
поделиться

Сначала давайте поймем Выделение памяти в Java: Стек и "куча" являются частью Памяти, которую JVM выделяет в различных целях. Стековая память предварительно выделяется потоку, когда это создается, поэтому, поток не может получить доступ к Стопке другого потока. Но "куча" доступна всем потокам в программе.

Для потока, Стек хранит все локальные данные, метаданные программы, ссылки на данные типа примитива и ссылки на объект. И, "куча" ответственна за устройство хранения данных фактического объекта.

Book book = new Book("Effective Java");

В вышеупомянутом примере, ссылочная переменная является "книгой", которая хранится в стеке. Экземпляр, созданный новым оператором-> новая Книга ("Эффективный Java"), хранится в "куче". Касательно переменной "книги" имеет адрес объекта, выделенного в "куче". Скажем, адрес 1001.

enter image description here

Рассматривают передачу примитивного типа данных т.е. интервала, плавания, дважды и т.д.

public class PrimitiveTypeExample { 
    public static void main(string[] args) {
       int num = 10;
       System.out.println("Value before calling method: " + num);
       printNum(num);
       System.out.println("Value after calling method: " + num);
    }
    public static void printNum(int num){
       num = num + 10;
       System.out.println("Value inside printNum method: " + num);
    }
}

, Вывод: Значение перед вызывающим методом: 10 Значений внутри printNum метод: 20 Значений после вызывающего метода: 10

международная цифра =10;-> это выделяет память для "интервала" в Стопке рабочего потока, потому что, это - тип примитива. Теперь, когда printNum (..) назван, частный стек создается в том же потоке. Когда "цифра" передается этому методу, копия "цифры" создается в стековом фрейме метода. цифра = num+10;-> это добавляет 10 и изменяет международную переменную в стековом фрейме метода. Поэтому исходная цифра вне стекового фрейма метода остается неизменной.

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

enter image description here

В вышеупомянутом примере, касательно переменной "книги" находится в стопке потока, выполняющего программу, и объект класса Книга создается в Пространстве "кучи", когда программа выполняет новую Книгу (). Эта ячейка памяти в "куче" отнесена "книгой". Когда "книга" передается как аргумент метода, копия "книги" создается в частном стековом фрейме метода в той же стопке потока. Поэтому скопированная ссылочная переменная указывает на тот же объект класса "Книга" в "куче".

enter image description here

ссылочная переменная в стековом фрейме метода устанавливает новое значение к тому же объекту. Поэтому это отражается, когда исходный касательно переменной "книги", получает ее значение. Обратите внимание, что в случае передающей ссылочной переменной, если она инициализируется снова в вызываемом методе, она затем указывает на новую ячейку памяти, и любая операция не влияет на предыдущий объект в "куче".

Поэтому, когда что-либо передается как аргумент метода, это всегда - объект Стека - или примитивная или ссылочная переменная. Мы никогда не передаем что-то, что хранится в "куче". Следовательно, в Java, мы всегда передаем значение в стеке, и это - передача значением.

3
ответ дан 22 November 2019 в 19:37
поделиться

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

Берут badSwap () метод, например:

public void badSwap(int var1, int var2)
{
  int temp = var1;
  var1 = var2;
  var2 = temp;
}

, Когда badSwap () возвраты, переменные передали, поскольку аргументы будут все еще содержать свои исходные значения. Метод также перестанет работать, если мы изменим тип аргументов от интервала до Объекта, так как Java передает ссылки на объект значением также. Теперь, вот то, где это становится хитрым:

public void tricky(Point arg1, Point arg2)
{
  arg1.x = 100;
  arg1.y = 100;
  Point temp = arg1;
  arg1 = arg2;
  arg2 = temp;
}
public static void main(String [] args)
{
  Point pnt1 = new Point(0,0);
  Point pnt2 = new Point(0,0);
  System.out.println("X: " + pnt1.x + " Y: " +pnt1.y); 
  System.out.println("X: " + pnt2.x + " Y: " +pnt2.y);
  System.out.println(" ");
  tricky(pnt1,pnt2);
  System.out.println("X: " + pnt1.x + " Y:" + pnt1.y); 
  System.out.println("X: " + pnt2.x + " Y: " +pnt2.y);  
}

, Если мы выполняем это основное () метод, мы видим следующий вывод:

X: 0 Y: 0
X: 0 Y: 0
X: 100 Y: 100
X: 0 Y: 0

метод успешно изменяет значение pnt1, даже при том, что это передается значением; однако, подкачка pnt1 и сбоев pnt2! Это - основной источник беспорядка. В основном () метод, pnt1 и pnt2 является не чем иным как ссылками на объект. При передаче pnt1 и pnt2 к хитрому () метод Java передает ссылки значением точно так же, как любой другой параметр. Это означает, что ссылки, переданные методу, являются на самом деле копиями исходных ссылок. Рисунок 1 ниже показывает две ссылки, указывающие на тот же объект после того, как Java передаст объект методу.

enter image description here
рисунок 1. Будучи переданным методу, объект будет иметь по крайней мере две ссылки

, Java копирует и передает ссылку значением, не объект. Таким образом управление методом изменит объекты, так как ссылки указывают на исходные объекты. Но так как ссылки являются копиями, подкачки перестанут работать. Ссылочная подкачка метода, но не исходные ссылки. К сожалению, после вызова метода, Вас оставляют только с неподкачанными исходными ссылками. Чтобы подкачка успешно выполнилась за пределами вызова метода, мы должны подкачать исходные ссылки, не копии.

3
ответ дан 22 November 2019 в 19:37
поделиться

Java передает параметры по значению. В Java нет возможности передать ссылку.

Но на уровне уровня привязки компилятора он использует ссылку, внутренне не предоставленную пользователю.

Это важно, так как экономит много памяти и улучшает скорость.

1
ответ дан Amit Sharma 22 November 2019 в 19:37
поделиться

Открытый класс Test {

static class Dog {
    String name;

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Dog other = (Dog) obj;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }

    public String getName() {
        return name;
    }

    public void setName(String nb) {
        this.name = nb;
    }

    Dog(String sd) {
        this.name = sd;
    }
}
/**
 * 
 * @param args
 */
public static void main(String[] args) {
    Dog aDog = new Dog("Max");

    // we pass the object to foo
    foo(aDog);
    Dog oldDog = aDog;

    System.out.println(" 1: " + aDog.getName().equals("Max")); // false
    System.out.println(" 2 " + aDog.getName().equals("huahua")); // false
    System.out.println(" 3 " + aDog.getName().equals("moron")); // true
    System.out.println(" 4 " + " " + (aDog == oldDog)); // true

    // part2
    Dog aDog1 = new Dog("Max");

    foo(aDog1, 5);
    Dog oldDog1 = aDog;

    System.out.println(" 5 : " + aDog1.getName().equals("huahua")); // true
    System.out.println(" part2 : " + (aDog1 == oldDog1)); // false

    Dog oldDog2 = foo(aDog1, 5, 6);
    System.out.println(" 6 " + (aDog1 == oldDog2)); // true
    System.out.println(" 7 " + (aDog1 == oldDog)); // false
    System.out.println(" 8 " + (aDog == oldDog2)); // false
}

/**
 * 
 * @param d
 */
public static void foo(Dog d) {
    System.out.println(d.getName().equals("Max")); // true

    d.setName("moron");

    d = new Dog("huahua");
    System.out.println(" -:-  " + d.getName().equals("huahua")); // true
}

/**
 * 
 * @param d
 * @param a
 */
public static void foo(Dog d, int a) {
    d.getName().equals("Max"); // true

    d.setName("huahua");
}

/**
 * 
 * @param d
 * @param a
 * @param b
 * @return
 */
public static Dog foo(Dog d, int a, int b) {
    d.getName().equals("Max"); // true
    d.setName("huahua");
    return d;
}

}

пример кода, чтобы продемонстрировать влияние изменений объекта на различные функции.

2
ответ дан 22 November 2019 в 19:37
поделиться

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

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

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

String name="Mehrose";  // name referencing to 100

ChangeContenet(String name){
 name="Michael"; // refernce has changed to 1001

} 
System.out.print(name);  //displays Mehrose

Довольно простой, потому что, поскольку я упомянул, Нельзя изменить скопированную ссылку в функции вызова. Но проблема с массивом при передаче массива Строки/Объекта. Давайте посмотрим.

String names[]={"Mehrose","Michael"};

changeContent(String[] names){
  names[0]="Rose";
  names[1]="Janet"

}

System.out.println(Arrays.toString(names)); //displays [Rose,Janet]

, Поскольку мы сказали, что не можем изменить скопированную ссылку в вызове функции, и мы также видели в случае единственного Строкового объекта. Причина является именами [] ссылка переменной против скажем, 200 и называет [0] ссылка против 205 и так далее. Вы видите, что мы не изменили имена [], ссылаются на него неподвижные точки к старому та же ссылка все еще после вызова функции, но теперь называет [0] и называет [1], ссылка была изменена. Мы Все еще стоим на нашем определении, что мы не можем изменить ссылку ссылочной переменной, таким образом, мы не сделали.

то же самое происходит, когда Вы передаете Студенческий объект методу, и Вы все еще можете изменить Студенческое имя или другие атрибуты, точка, мы не изменяем фактический Студенческий объект скорее, мы изменяем содержание его

, Вы не можете сделать этого

Student student1= new Student("Mehrose");

changeContent(Student Obj){
 obj= new Student("Michael") //invalid
 obj.setName("Michael")  //valid

}
0
ответ дан 22 November 2019 в 19:37
поделиться

Как выпускник информатики и как Разработчик программного обеспечения в общем... и изученный компиляторы и языки программирования... Java передает объекты ссылкой. Который передает значение ссылки, которая не отличается о том, как C++ или C делают.

-2
ответ дан 22 November 2019 в 19:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: