【问题标题】:Why does java use both pass-by-value and pass-by-reference? [duplicate]为什么java同时使用传值和传引用? [复制]
【发布时间】:2012-12-06 19:01:30
【问题描述】:

可能重复:
Is Java “pass-by-reference”?

也许我遗漏了一些东西……但我真的不明白为什么 Java 会同时使用按值传递和按引用传递。 为什么不只使用一种范式?

【问题讨论】:

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


【解决方案1】:

它没有。 Java 纯粹是按值传递。处理对象时传递的值是对象引用,但这与“通过引用传递”无关

按引用传递意味着函数可以传递一个变量并在调用函数中更改该变量的内容。这在 Java 中不存在。

例如:

void foo() {
    int a;

    a = 42;
    bar(a);
    System.out.println(a); // Will ALWAYS be 42
}

void bar(int b) {
    b = 67;
}

对比C++,确实有传递引用:

// C++ code
void foo() {
    int a;

    a = 42;
    bar(a);
    cout << a; // 67?!
}
void bar(int& a) { // <== Note the &
    a = 67;
}

Java 没有 C++ 中的 &amp;(或 C# 中的 out / ref)。

您可能正在考虑对象引用,这是对“引用”一词的完全独立使用,而不是传递引用中的“引用”。让我们看一个带有对象的示例:

void foo() {
    Object o1, o2;

    o1 = new Object();
    o2 = o1;
    bar(o1);
    System.out.println(o1 == o2); // Will ALWAYS be true
}

void bar(Object o) {
    o = new Object();
}

如果 Java 有按引用传递(并且我们使用它将对象变量传递给 bar),则 foo 中的 == 将是错误的。但事实并非如此,也没有办法做到这一点。

对象引用允许您更改传递给函数的对象的状态,但您不能更改调用函数中包含它的变量。

【讨论】:

  • 有区别,但不是完全分开:函数确实可以更改它传递的对象。
  • @MarkoTopolnik:不,它是完全分开的。在传递引用中,“引用”是对变量的引用。 Java 传递的是一个引用对象的值。完全不同的东西。
  • 它们也相关,通过传入的实体可以变异的属性,以及调用者观察到的效果。在 Java 中,你改变 instance 变量;在 pass-by-reference 中,您可以改变 local 变量。仅从非常狭隘的角度来看,它们是“完全不同的”。
  • @MarkoTopolnik:我不想就这个话题进行冗长的讨论,但是有一个根本的区别:你不会改变变量的状态通过引用传递,您完全破坏了它的值并用新值替换它。对象引用允许您修改对象的状态,但不能完全清除对象本身并替换它。 :-) (我们可以把“心胸狭窄”之类的词排除在理性交流之外吗?)
  • 不要误会我的意思,我完全同意“基本”方面!我只是争辩说“根本区别”=/=“完全不相关”。顺便说一句,在 Java 中,您也可以“清除对象”,而不是传入的对象,而是实例变量引用的对象。这实际上只是更深入地了解您可以更改的内容。关于“狭隘”,如果它带来了意想不到的指责,请改为“狭隘”:)
【解决方案2】:

Java 总是“按值传递”。所以原语和 Object 的 (reference) 都是按值传递的。

编辑

是的,对象不是直接传递的,我们总是用它们的引用来引用它们。所以Object的引用是按值传递的。

【讨论】:

  • 不,对象不是按值传递的。对象引用按值传递。这是一个巨大的差异。
  • 同意@T.J.Crowder;我没有说清楚。我已经更新了我的帖子。谢谢指正:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-02
  • 2013-03-06
相关资源
最近更新 更多