23
public class program1{

    public static void main(String args[]){

        java.util.Vector vc=new java.util.Vector();

        vc.add("111");
        vc.add("222");

        functioncall(vc);

        vc.add("333");

        System.out.println(vc);

    }

    public static void functioncall(java.util.Vector vc){     

        vc=null;    

    }
}

上述程序的输出是 [111,222,333]。但是,当我运行以下程序时,输出为 [333]。当我们传递引用时感到困惑,无论是按值调用还是按引用调用,它是如何工作的?为什么

public class program1{

    public static void main(String args[]){

        java.util.Vector vc=new java.util.Vector();

        vc.add("111");
        vc.add("222");

        functioncall(vc);

        vc.add("333");

        System.out.println(vc);

    }

    public static void functioncall(java.util.Vector vc){

        vc.removeAllElements();  

    }
}
4

11 回答 11

23

它传递引用的

为了厚颜无耻地盗用我不久前在这里看到的一个类比,假设您使用的每个标识符都是一张写有地址的纸。地址指向一所房子。

您可以更改房子(例如,通过向矢量添加对象或清除它),但您仍然拿着同一张纸,地址仍然会将您带到同一房子。

如果将向量设置为空,那么您所做的就是删除地址。

这篇文章更详细地解释了它。

于 2012-05-25T07:21:43.063 回答
3

您将 vc 作为参考副本传递(始终)。然后执行 vc = null;or vc = new Vector(),您只需修改来自 vc 本地属性的引用,因此 main 没有更改是正常的。

于 2012-05-25T07:22:04.423 回答
2

它是按值调用的。在这两种情况下,您都将引用值放在方法的参数中,即方法的本地引用。

于 2012-05-25T07:25:53.740 回答
2

Java 编程语言总是使用按值调用。在 Java 中,方法的所有参数都是按值调用或按值传递的。Cay S. Horstmann 和 Garry Cornell 在他们非常著名的书“Core Java Volume - I Fundamentals”中提到 Java 编程语言总是使用按值调用。这意味着该方法获取所有参数值的副本,并且该方法不能修改传递给它的任何参数变量的内容。Java 使用两种方法参数:

  • Java 原始类型
  • Java 对象引用

当您尝试将原始类型传递给方法时,它看起来非常直接和简单,但在将对象传递给方法时变得晦涩难懂。有趣的是,当一个对象引用被传递给一个方法时,该方法得到一个对象引用的副本,并且原始副本和正式副本都引用同一个对象,因此在方法内可以更改对象参数的状态.

以下文章很好地解释了按值调用和按引用调用

于 2013-01-19T03:35:56.813 回答
1

Java 使用对象引用。参数是参考值。所以它是按值调用的,其中值是对象的引用。

于 2012-05-25T07:20:49.463 回答
1

vc 是一个新变量,其中包含用于调用该方法的向量的引用。将其更改为 null 不会影响原始向量,因为此引用是原始向量引用的副本。

但是由于这是对原始向量的引用,因此对向量的任何修改实际上都会改变原始向量。所以java总是使用按值调用,这里的值恰好是一个引用。

于 2012-05-25T07:20:52.977 回答
1

Java 和 C总是按值调用。引用调用这个术语严格适用于 C++,我们在形式参数中使用 & 运算符。在对象引用的情况下,引用从实际参数复制到形式参数。

于 2013-04-07T17:20:02.253 回答
1

在java中按值传递意味着传递要传递的值的副本。在java中通过引用传递意味着传递地址本身。在 Java 中,参数总是按值传递。Java 仅支持按值传递。

对于 Java 对象,对象引用本身是按值传递的,因此原始引用和参数副本都引用同一个 Java 对象。Java 原语也是按值传递的。

于 2014-01-07T19:40:07.143 回答
0

使用Java“按引用传递”,引用本身是按值传递的。

因此,您不能更改引用本身,但可以更改引用指向的对象。

因此,您的removeAll呼叫会起作用,Vector因此您会看到结果。但是,如果您更改引用本身,例如:

vc = null

或者,

vc = new Vector();

这些更改指向一个新的(或 null )对象,因此之后的任何更改都不会反映在main

于 2012-05-25T07:24:51.257 回答
0

Java 使用“按值调用概念”。如果它的堆栈和堆是可视化的,那么 java 会尝试在本地工作空间中查找任何变量的值,如果在本地找不到它,那么它会尝试在堆中的对象中查找。

例子

class Foo
{

int x;

public void call(int x)

{

    x++;

}

public static void main(String[] args)

{

       Foo foo = new Foo();

       foo.x = 5;

       System.out.println(foo.x);

       foo.call(foo.x);

       System.out.println(foo.x); 


}


}

上述程序的输出将是:5、5 说明:在 main 方法中,x 的值在“foo”的引用上赋值为 5:在调用方法中,工作区中有名为“x”的局部变量(作为参数传递)。所以它是值只会在其工作区中更改。当此函数的控制返回到 main 方法时。在 main 的工作区中,“x”的值仍然是 5。

例子

class Foo

{

int x;

public void call(int y)

{

    x++;

}

public static void main(String[] args)

{

       Foo foo = new Foo();

       foo.x = 5;

       System.out.println(foo.x);

       foo.call(foo.x);

       System.out.println(foo.x); 

}


}

上述程序的输出为: 5 , 6

描述:在main方法中,x的值在“foo”的引用上赋值为5:在调用方法中,工作区中没有名为“x”的局部变量(作为参数传递)。所以java在引用中找到它“调用”函数被调用并且“x”的值是 5,调用方法将其值增加到“6”,因此它的值将被更改引用,即“foo”。当该函数的控制返回到 main 方法时。现在在 main 的工作区值“x”是 6,因为这里我们在 foo 引用上打印了“x”。

我希望这能帮助你理清概念。

问候, 苏希尔耆那教

于 2012-12-23T03:35:46.460 回答
0

值传递

实际参数(或参数表达式)被完全评估,结果值被复制到用于在方法/函数执行期间保存形式参数值的位置。该位置通常是应用程序运行时堆栈上的一块内存(这是 Java 处理它的方式),但其他语言可以选择不同的参数存储。

Pass-by-reference 形式参数仅充当实际参数的别名。每当方法/函数使用形式参数(用于读取或写入)时,它实际上是在使用实际参数。 Java 是严格按值传递的

于 2013-04-01T18:12:52.960 回答