2012-02-02 4 views
0

Я читаю про Pass по значению и передаю по ссылке в java, у меня появилось много статей, некоторые из которых говорят, что Java следует только «Pass by value», а некоторые из них говорят о некоторых разница между примитивными и объектом. поэтому я написал следующий пример кода. и ввод вывод также. Прокомментируйте и поделиться тем, что именно ответ.Передать по значению и передать по ссылке в 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 
+0

см. Http://stackoverflow.com/questions/40480/ is-java-pass-by-reference –

+0

Это большая разница между 'i.name =" rishu "и' i = rishu' (или 'i = new Emp (" rishu ", ...)'). Первый изменяет объект _saved_ в 'i', второй меняет' i'. –

ответ

10

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

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

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

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

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

+0

Хороший ответ, но исправьте опечатку: ..it ссылается на тот же _object_, поэтому ... – quaylar

+0

@quaylar: thanks, done –

+0

Точно так же, почему строковый буфер не работает. – Pedantic

1

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

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

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

Когда этот метод выходит, сотрудник будет иметь имя подбородка.

public void doChange(Emp i) { 
    i.setName("chin boon"); 
} 
+0

На самом деле, спасибо, пожалуйста, помогите мне понять, как работает класс Employee. Я модифицировал метод как модификацию для String и StringBuffer. – Pedantic

1

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

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

Например:

Dog aDog = new Dog("Max"); 

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

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

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

1

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

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

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

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

Значение StringBuffer перед методом: -> ABC значение i-го> ABC Привет стоимости StringBuffer после того, как метод: -> ABC

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

И наконец:

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

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

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

Смежные вопросы