通过Java传递值或通过引用传递?

时间:2011-09-04 19:32:11

标签: java

我阅读了很多文章,并且都说Java是值得传递的。但我仍然没有解释传递值和参考值之间的区别。我写了一个示例程序,它就像这样执行..

public class PassByValue {

   private int a;
   private int b;

   public PassByValue(int a, int b) {
    this.a = a;
    this.b = b;
   }

   public static int mul(int a, int b) {

       int z = a * b;
       System.out.println("The Value of Z inside mul: " + z);
       return z;

   }

   public static void main(String args[]) {

    int z = 100;

        int x = 40;
        int y = 20;

    mul(x,y);

    PassByValue pass = new PassByValue(x,y);
    mul(pass.a,pass.b);

        System.out.println("The Value of Z" + z);

   }

}

执行

800
800 and 
100

任何人都可以向我解释这些问题......

  1. Pass By Value是什么意思......
  2. 答案:它只是将存储在变量中的数字或值传递给函数。我是对还是错。

    1. 你怎么说Java是通过价值?
    2. 为什么Java是按值传递而不是通过引用?
    3. 以上程序Tries是否显示了Pass by value和Reference ...的示例,但仍然只通过Pass by Value执行...我编写了该程序。

4 个答案:

答案 0 :(得分:18)

混淆可能是因为变量首先不能包含对象。变量只能包含对象的引用。 (换句话说,根本不传递对象,不是通过引用传递,而不是通过值传递。)

一旦你意识到这一点,很明显Java中没有任何传递引用。引用对象的变量存储引用,此引用按值传递。


  

1。什么是按价值传递意味着......

     

答案:它只是将存储在变量中的数字或值传递给函数。我是对还是错。

没错。传递变量中包含的,而不是变量本身。

  

<强> 1。 How do you sayJava是通过价值?

Java是按值传递的,因为原语是按值传递的,引用是按值传递的。 (物体永远不会传递。)

例如,您无法在Java中实现swap方法。即,你做不到

String str1 = "hello";
String str2 = "world";
swap(str1, str2);
// str1 can't refer to anything but "hello"
// str2 can't refer to anything but "world"
  

2。为什么Java是按值传递而不是通过引用?

如上所述,甚至引用都是按值传递的。

答案 1 :(得分:13)

你的答案是正确的,但你缺乏细节。如果你这样做

Dog d = new Dog()

d是对Dog实例的引用,即值传递意味着您将d传递给方法

walkDog(d);

将引用的a 副本(即引用的值,而不是引用本身)传递给方法。因此,您有两个对Dog的实例的引用,一个在调用范围中,一个在被调用范围内。让我们说在walkDog方法中有一行

d = new Dog();

方法中的d引用指向新狗。首次调用该方法的原始引用仍然指向original Dog。如果Java通过引用传递,则相同的引用,而不是引用的副本将在方法中使用,因此更改引用的值将影响调用和被调用的引用范围。

编辑 - 根据你的评论,我想明确的事情。由于原始作用域和方法作用域中的引用都指向相同的对象,因此您仍然可以在两个作用域中更改该对象上的内容。所以,如果你这样做

d.drinkWater();

walkDog方法中的

drinkWater更改了dog对象上的某个变量,因为两个引用都指向同一个对象,该对象已更改。

这只是引用在每个范围内的实际区别。但它确实出现了很多。

答案 2 :(得分:3)

您可以将pass-by-value视为仅传递变量中包含的值而不传递变量本身。然后将值复制到另一个临时变量中。相反,您可以将传递引用视为传递实际变量而不进行临时复制,以便变量中的任何更改都“保存”。虽然还有更多内容,但可能更容易思考它

答案 3 :(得分:1)

我认为,如果Java支持通过引用或值传递,那么应该清楚地了解在其实现中使用Java中的类的实例的方式。这一切都恰好是实例的类型 - 可变/不可变,它将决定我们将事物传递给函数的方式!这取决于你探索这种差异!

让我澄清一下为什么没有必要追回传递什么的论点?!考虑一下...... 第一个代码:

    void foobar(int *a){
        printf("%d", *a);
    }

    int main(){
        int a = 5;
        foobar(&a);
        return 0;
    }

在这个C代码中,你传递了什么......变量'a'的地址。这恰好是参考传递! :)

让我们考虑另一个...... 第二个代码:

    void foobar(int* a){
        printf("%d", *a);
    }

    int main(){
        int a = 5;
        int *p = &a;
        foobar(p);
        return 0;
    }

在这个C代码中,我通过了什么......?变量'p'的值与指针或其他东西无关:P

那么你怎么称呼它作为值传递/通过引用传递?我留给你了!但我们需要关注的是我们将如何实施...... :)

所以在Java中......我们可以说 - 我们可以说 - 它支持“按值传递”或“通过某个实例的引用传递”而不是“通过引用传递”

***只有我可以清楚地得出结论的是Java中的原始数据类型。由于没有指针可以在没有实际变量的情况下编辑字节的内容,因此我们不能在Java中通过引用传递(我的意思是原始数据类型)。