Передать по значению и передать по ссылке в Java - PullRequest
0 голосов
/ 02 февраля 2012

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

Я проверил классы Int, String, StringBuffer и Employee, теперь он работает как передача по ссылке только для класса Employee.

package test;
class Emp {
    public String name="";
    public int age=0;

    public Emp(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }
    public String toString() {
        return "Name: "+ this.name + "....Age: "+ this.age;

    }
}
public class Class1 {
    public Class1() {
        super();
    }

    public void doChange(int i) {
        i = i +10;
        System.out.println("Value of Integer in Method:>"+ i);
    }

    public void doChange(Emp i) {
        i.age=29;
        i.name="rishu";
        System.out.println("Value of Employee In Method "+i.toString());
    }

    public void doChange(String i) {
        i = i + " Hello";
        System.out.println("value of i->"+ i);
    }


    public static void main(String[] args) {
        int i =10;
        String str="XXX";
        Class1 c= new Class1();
        StringBuffer sb= new StringBuffer();
        Emp e= new Emp("abhi",28);       

        sb.append("ABC ");
        System.out.println("");
        System.out.println("Value of Integer before Method:->"+ i);
        c.doChange(i);
        System.out.println("Value of Integer after Method:->"+ i);
        System.out.println("");
        System.out.println("Value of String before Method:->"+ str);
        c.doChange(str);
        System.out.println("Value of Integer after Method:->"+ str);
        System.out.println("");
        System.out.println("Value of StringBuffer before Method:->"+ sb);
        c.doChange(sb.toString());
        System.out.println("Value of StringBuffer after Method:->"+ sb);
        System.out.println("");

        System.out.println("Value of Employee before Method:->"+ e.toString());
        c.doChange(e);
        System.out.println("Value of Employee after Method:->"+ e.toString());
    }
}

Выход:

Value of Integer before Method:->10
Value of Integer in Method:>20
Value of Integer after Method:->10

Value of String before Method:->XXX
value of i->XXX Hello
Value of Integer after Method:->XXX

Value of StringBuffer before Method:->ABC 
value of i->ABC  Hello
Value of StringBuffer after Method:->ABC 

Value of Employee before Method:->Name: abhi....Age: 28
Value of Employee In Method Name: rishu....Age: 29
Value of Employee after Method:->Name: rishu....Age: 29

Ответы [ 5 ]

10 голосов
/ 02 февраля 2012

Java только для передачи по значению.

Однако для объектов то, что передается по значению, является ссылкой на объект . Нет, это не то же самое, что передача по ссылке. Разница заключается в следующем:

Если вы делаете это:

public void doChange(Emp i) {
    i = new Emp("changed!", 42);
}

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

1 голос
/ 02 февраля 2012

Значение целого числа до метода: -> 10 Значение целого числа в методе:> 20 Значение целого числа после метода: -> 10

Здесь нет ничего удивительного.Вы передаете значение 10 методу, оно увеличивается и отображается правильно.После возврата из вызова метода переменная i остается неизменной.

Значение строки до метода: -> XXX значение i-> XXX Hello Значение целого числа после метода: -> XXX

Строки являются неизменяемыми классами, поэтому изменить их невозможно.Вы можете только переназначить значение, как вы это делали в своем примере.Хитрость заключается в том, чтобы понять, что вы получаете скопированное значение ссылки, ведущее к объекту XXX.Теперь вы создаете новый объект i + "Hello" и переопределяете предыдущую ссылку i.Таким образом, объект XXX не изменяется, однако в методе вы его не печатаете - вы печатаете объект, созданный в методе.

Значение StringBuffer перед методом: ->Значение ABC для i-> ABC Hello. Значение StringBuffer после метода: -> ABC

Это тот же случай, что и в приведенном выше коде, поскольку toString() дает новый объект String.

И наконец:

Значение сотрудника до метода: -> Имя: abhi .... Возраст: 28 Значение сотрудника в имени метода: rishu .... Возраст: 29Значение Employee после метода: -> Имя: rishu .... Возраст: 29

Это идеальная демонстрация PASS BY VALUE Вы создаете объект Employee,но вы передаете REFERENCE этому объекту в качестве параметра метода.Теперь, запомните это на всю жизнь , эта ссылка скопирована, поэтому вы получите копию ссылки, доступную для работы внутри метода. ПОЧЕМУ JAVA ВСЕГДА ПРОХОДИТ КОПИЕЙ .Однако эта скопированная ссылка все еще указывает на тот же объект Employee, который вы создали ранее.Таким образом, если вы будете использовать эту ссылку для изменения объекта, на который он указывает, вы измените исходный Employee.Вот почему вы можете увидеть эффект изменения в выводе.

Bruce Eckel имеет хороший пример ссылок и объектов в Java.Думайте об объекте как о телевизоре, а об объекте - как о пульте дистанционного управления.Если вы передадите ссылку на другой метод в качестве аргумента, у вас будет скопированный пульт дистанционного управления в этом методе.Если вы нажмете кнопку «выключить» в методе, телевизор все равно будет выключен, даже если вы не использовали оригинальный пульт;)

1 голос
/ 02 февраля 2012

Java передает параметры в методы, используя семантику передачи по значению. То есть copy of the value каждого из указанных аргументов вызова метода передается методу в качестве его параметров.

Очень четко заметьте, что многие люди путают терминологию "ссылки" в отношении ссылок Java на объекты и передают по семантике вызова по ссылке. Дело в том, что при работе со ссылками Java на объекты копия значения ссылки - это то, что передается методу - оно передается по значению. Именно поэтому, например, вы не можете изменить (исходную, вызывающую) ссылку на объект изнутри вызываемого метода.

Например:

Dog aDog = new Dog("Max");

вы определяете указатель на объект Dog aDog, а не сам объект Dog.

public void foo(Dog d) {
   d = new Dog("Bingo");
}

переданная переменная не изменена! После вызова foo, aDog все еще указывает на собаку «Макс». Передает значение d в foo, значение указателя аналогично адресу памяти.

1 голос
/ 02 февраля 2012

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

Когда этот метод завершается, сотрудник будет не чин Бун, а чем-то еще, что вы установили перед тем, как ввести этот метод.*

public void doChange(Emp i) {
    i = new Emp("chin boon", 42);
}

При выходе из этого метода у сотрудника будет имя chin boon.

public void doChange(Emp i) {
    i.setName("chin boon");
}
0 голосов
/ 03 июня 2018

Мы можем сделать как в java «Передача по значению», так и в «Передаче по ссылке» здесь пример обоих.

Пример передачи по значению

class PassByValue{
String name="java";
void display(String name)
{
    name="Java Programming";
}
public static void main(String arg[])
{
    PassByValue p=new PassByValue();
    System.out.println("Before changes : "+p.name);
    p.display("C++");
    System.out.println("After changes : "+p.name);
}}

Передача по справочному примеру

class PassByReference{
String name="Java";
void display(PassByReference p)
{
    name="Java Programming";
}
public static void main(String arg[])
{
    PassByReference p=new PassByReference();
    System.out.println("Before changes : "+p.name);
    p.display(p);
    System.out.println("After changes : "+p.name);
}}

Вы можете проверить возвращаемое значение и возвращающий объект в Java, нажав здесь: Возвращаемое значение и возвращаем объект в Java

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