按值传递并在java中通过引用传递

时间:2012-02-02 09:02:06

标签: java oop core

我正在阅读关于Pass by Value和通过引用传递的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 个答案:

答案 0 :(得分:10)

Java只是按值传递。

但是,对于对象,通过值传递的是对对象的引用。不,这与传递参考不同。区别在于:

如果你这样做:

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

它在方法之外绝对没有效果 - 因为引用i是在方法之外使用的引用的副本。但是,它引用同一个对象,因此如果使用引用来更改对象的字段,则这些更改在方法外部可见。

答案 1 :(得分:1)

Java中没有通过引用传递,只传递值。

当此方法退出时,员工不会是下巴,而是在您输入此方法之前将其设置为其他内容。

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

当此方法退出时,员工将获得名称chin boon。

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

答案 2 :(得分:1)

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仍然指向“Max”Dog。将d的值传递给foo,指针的值类似于内存地址。

答案 3 :(得分:1)

  

方法前的整数值: - > 10方法中整数的值:> 20方法后的整数值: - > 10

这里不足为奇。将值10传递给方法,它会递增并正确显示。从方法调用返回后,i变量保持不变。

  

方法前字符串的值: - > x-值的XXX-> XXX方法后的整数Hello值: - > XXX

字符串是不可变类,因此无法更改它。您只能重新分配值,就像您在示例中所做的那样。这里的诀窍是要理解,您收到一个复制的引用值,该值通向对象XXX。现在,您正在创建新对象i + "Hello"并覆盖先前的引用i。因此,对象XXX不会更改,但是在您不打印它的方法中 - 您正在打印在方法中创建的对象。

  

方法之前StringBuffer的值: - > i-> ABC的ABC值方法之后的StringBuffer的ABC Hello值: - > ABC

这与上面的代码中的情况相同,因为toString()会产生一个新的String对象。

最后:

  

方法前员工的价值: - >姓名:abhi ....年龄:28员工的价值方法名称:rishu ....年龄:29员工的价值方法: - >名称:rishu。 ......年龄:29

这是PASS BY VALUE 的完美展示 您正在创建对象Employee,但是您将REFERENCE作为方法参数传递给此对象。现在,记住这一生,这个引用是COPIED,因此您将收到一份可供您在方法内部使用的参考副本。 为什么JAVA总是以复制方式通过。 但是,此复制的引用仍指向您之前创建的同一对象Employee。因此,如果您将使用该引用来修改它所指向的对象,则可以修改原始Employee。这就是为什么你可以在输出中看到变化效果的原因。

Bruce Eckel有一个很好的Java参考和对象示例。将对象视为电视,将参考视为遥控器。如果将参考传递给其他方法作为参数,则在此方法中将具有复制的远程控制。如果按方法中的“关闭”按钮,即使您没有使用原始遥控器,电视仍然会关闭;)

答案 4 :(得分:0)

我们可以在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中的返回值返回对象return value and return object in java