澄清声明:“对象引用由Java中的值传递”

时间:2015-07-18 23:04:25

标签: java parameter-passing pass-by-reference pass-by-value

由于我对Java比较陌生,我仍然不确定基本的值传递/传递引用的东西。我在SO上看过这个问题:Is Java “pass-by-reference” or “pass-by-value”?,这似乎有一些非常好的答案。在一个这样的答案中引用的文章之一是Java is Pass-by-Value, Dammit!

在阅读了答案和文章之后,我想:

  1. Java中的所有内容都是按值传递的,没有通过引用传递(从读数开始)。
  2. 原语总是按价值传递(我的想法)
  3. 通过引用传递对象(我的想法)
  4. 上述(3)实际上是错误的,对象引用按值传递(从文章开始)。
  5. 所以现在,我在第3点和第4点之间挣扎。我写了这个简单的类来清除一些东西:

    package Chap_1;
    
    /**
     * Created by user1 on 7/18/15.
     */
    public class JavaTest1 {
    
        private double balance;
    
        public JavaTest1(double amt) {
            balance = amt;
        }
    
        public double getBalance() {
            return balance;
        }
    
        public void method1() {
            JavaTest1 obj1 = new JavaTest1(300.00);
            System.out.println("Balance in method1 before method2= " + obj1.getBalance());
            method2(obj1);
            System.out.println("Balance in method1 after method2 = " + obj1.getBalance());
        }
    
        public void method2(JavaTest1 o) {
            o.balance -= 100.00;
        }
    
        public static void main(String[] args) {
            JavaTest1 j1 = new JavaTest1(500.00);
            System.out.println("Balance in main before= " + j1.getBalance());
    
            j1.method1();
            System.out.println("Balance in main after = " + j1.getBalance());
    
        }
    }
    

    使用此代码,我得到输出:

    Balance in main before= 500.0
    Balance in method1 before method2= 300.0
    Balance in method1 after method2 = 200.0
    Balance in main after = 500.0
    

    我的观察是:

    1. 总体而言,事情开始于一个JavaTest1对象j1,起始余额为500. j1然后调用method1()
    2. method1()中,创建了另一个JavaTest1对象,余额为300。method1()然后调用method2()
    3. method2()中,传递了JavaTest1类型的对象。然后,此方法从传递给它的对象引用的余额中扣除100。
    4. 当我运行代码时,我发现method1中创建的对象的余额在method2()中减少到200。
    5. 现在这就是我的困惑所在。如果对象引用作为值传递,则method2()中的余额扣除不应修改method1()中创建的对象。但是因为它确实修改了平衡,所以它实际上并不是说对象总是作为引用传递,证明method1()method2()都在同一个对象上运行。否则,method2(JavaTest1 o)应创建另一个JavaTest1类型的对象,其引用称为o

3 个答案:

答案 0 :(得分:0)

实际上这个问题只是由于对语句3和4的误解造成的。“对象通过引用传递”意味着如果一个对象被用作方法的参数,对该对象的引用将被传递给该方法 - 将此引用视为具有特定含义的int。 “对象引用按值传递”表示引用本身将按值传递。这两者并不相互排斥。

答案 1 :(得分:0)

尽管对象似乎是通过引用传递的,但它的实际工作方式是对对象的引用按值传递。如果在函数内将对象类型的形式参数更改为另一个对象(或为null),则可以区分 - 调用者传递的实际参数不会改变,换句话说调用者不会看到作业。

(如果调用者要查看对被调用函数中的形式参数的赋值,该参数将代表通过引用传递。例如,C#具有outref参数用于这些目的。 )

答案 2 :(得分:0)

好的,让我们想一想。在这一行:

JavaTest1 j1 = new JavaTest1(500.00);

创建一个JavTest1对象并在j1中保存对它的引用(基本上是指向它的指针)。如你所料,balace是500.00

然后你致电method1

j1.method1();

method1内,您可以创建 JavaTest1对象obj并将其余额设置为300.00请注意,这是一个全新的对象,具有自己的平衡。

当您致电method2时,您正在对您创建的对象obj进行调用。您从余额中减去100.00,确保余额为200.00

然后从该方法返回

System.out.println("Balance in main after = " + j1.getBalance());

j1打印出余额 - *没有被任何内容触及,因此仍为500.00

这里的关键是你有两个独立的对象,按值调用或引用并不重要,因为你只有两个完全独立的对象。