实例变量是否通过Java引用传递?

时间:2011-03-10 21:47:32

标签: java variables reference pass-by-reference

现在我知道Java纯粹是按值传递,但实际变量是通过引用传递的吗?

这就是我的意思(我知道这段代码很糟糕,但它是伪代码:

//Instance variables
private Object[] array = new Object[10];
array[4] = new Object[5];

//Private method
private Object ar(int x)
{
     return array[x];
}

//Inside Main or some other method
ar(4)[0] = "Foo";

现在,array[4]中数组的第一个插槽是否会更改为“Foo”,因为array是一个实例变量?

澄清:

我知道 一切 是按值传递的。但是我们正在谈论调用实例变量中包含的东西,请关注它。感谢。

8 个答案:

答案 0 :(得分:5)

是的,array[4]中的第一个广告位将更改为"Foo"

在Java中,一切都按值传递。传递对象时,对值的引用将按值传递。对于您的示例,array[4]中包含的对象是从ar方法返回的。

答案 1 :(得分:4)

永远不会传递

变量。只包含它们包含的值。那就是:如果它是一个实例变量或其他它没有区别(至少为了争论“传递什么”)。

请记住,对象是它是什么,没有对象的隐式复制/克隆/复制 - 这包括数组对象 - 本身(认为基元是自我表示的不可变实体)。

快乐的编码。


更新:我找到了此链接,我喜欢它。 Call by object。这个词归于Liskov。

  
    

但是没关系,你唯一需要知道的是 Python的 Java的模型既不是“按值调用”也不是“按引用调用”(因为任何尝试使用 [思考]那些术语[正在考虑这些术语] ......)最准确的描述是CLU的“按对象调用”“通过共享调用”。或者,如果您愿意,“按对象引用调用”。

  

总结了差异:

  
    

“特别是因为突变而不是值得称呼         由被调用例程执行的参数将被显示         呼叫者,召集者。并且因为访问而不是参考         没有给出调用者的变量,而仅仅是某些变量         对象“。

  

只有在Java中,“call-by-sharing”是通过“传递引用的值”来实现的 - 一个实现细节,不需要考虑它来描述调用语义,对象或对象-identity

答案 2 :(得分:1)

来自Java的作者:“Java中只有一个参数传递模式 - 按值传递 - 这有助于保持简单。” Java编程语言,第2版。作者:Ken Arnold和James Gosling,第2.6.1节,第40页,第3段。

答案 3 :(得分:1)

Java Lang Spec:http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.1

§4.1有......两种数据可以......作为参数传递......:原始值(§4.2)和参考值

§4.3参考值(通常只是参考)是指针到这些对象

因此Java通过“值”,或“参考值”,或“引用”或“指针”。 (忽略原语)

所有4个版本均受语言规范认可。

现在我们可以请停止这个文字游戏。我们都知道传递的是什么,还不够吗?我们怎么称它通过玫瑰?

答案 4 :(得分:0)

是的,该代码会将array[4][0]设置为“Foo”。 array是一个实例变量的事实是无关紧要的。

答案 5 :(得分:0)

嗯,我通过运行一个非常简单的测试回答了我自己的问题,但是已经留下的一些答案有助于澄清事情。我知道类似于14种编程语言的东西,所以有时语言会变得模糊不清。

public class ArrayPassTest {

    private Object[] array;

    public ArrayPassTest()
    {
        array = new Object[10];
        array[4] = new Object[10];
    }

    public Object[] ar(int x)
    {
        return (Object[])array[x];
    }

    public static void main(String[] args) {
        ArrayPassTest apt = new ArrayPassTest();

        apt.ar(4)[0] = "Foo";

        System.out.println(apt.ar(4)[0]);
        System.out.println(apt.ar(4)[5]);

    }

}

输出:

Foo
null

感谢您的帮助!

答案 6 :(得分:0)

  

我知道一切都过去了   值。但我们正在谈论   调用实例中包含的东西   变量,请关注这一点。   感谢。

所有内容都包含“实例变量中包含的内容”。

当然这很明显?

答案 7 :(得分:-1)

考虑它的最佳方式是传递变量的地址,除非它是原始的。 (将数组视为非原始数组)。这将引导您获得运行测试程序所得到的答案,并解释原因。

(术语“by-reference”,“by-value”,“instance”在这种情况下含糊不清,令人困惑。)