【问题标题】:Why Java not allow C# "out" feature for method parameters [duplicate]为什么Java不允许方法参数的C#“out”功能[重复]
【发布时间】:2012-04-26 05:46:51
【问题描述】:

可能重复:
Why there is no way to pass by reference in java

谁能告诉我为什么Java在处理方法参数以通过引用传递时不提供C#“out”类型功能? 我的意思是为什么它不允许我们传递像布尔值这样的原始数据类型,例如,通过引用传递。我也尝试过包装类 java.lang.Boolean 但仍然无济于事。它仍然不允许我通过引用传递变量。
Java 甚至在版本 7 中仍然没有为我们提供这个有什么具体原因吗?

【问题讨论】:

  • 当你设计一门语言时,你只需要在某个地方做一个剪辑。一种语言的不必要功能越多,它的用处就越少……
  • .Net (C#) 占据了后发优势,它们展示了应用程序开发人员在 Java 中缺少的内容,并结合了“通过原始类型的引用”。现在 Java 最初的设计不允许,现在 Oracle 提供它可能很复杂,JVM/JRE 如何管理堆栈和堆,现在添加此功能还有许多其他技术限制。
  • @Pritesh:Java 并不是第一种被发明的语言,在 Java 之前我们已经有 种语言,所以“后发优势”并不是一个强有力的论据.
  • 嘿@Arafangion 我知道没有。 Java 之前的语言 :)Java 和 .Net 是 C++ 的衍生品,C++(带有 OS 攻丝功能)回答了应用软件开发中的大多数问题,除了生产力。 Java 是第一个比 C++ 具有高生产力的产品,因为它们从 C++ 中删除了不易使用的功能。 .Net 有一些时间,所以他们注意到程序员在 Java 中缺少哪些 c++ 类功能,并将它们合并到 .Net 中,例如运算符重载。
  • @Pritesh:这非常值得商榷。好奇你没有提到 BCL 的影响。

标签: java pass-by-reference out


【解决方案1】:

Java 只有传值。这是设计语言时做出的决定。

只有一种参数传递模式——按值传递——这有助于保持简单。

-- James Gosling 等人,Java 编程语言,第 4 版

如果你愿意,你可以将你的布尔值作为一个成员放入一个可变类中(你不能使用Boolean,因为它是不可变的),并传递一个对该类的引用。 Apache Commons 甚至有一个名为 MutableBoolean 的类供您使用。

【讨论】:

  • 谢谢马克。是的,Apache Commons MutableBoolean 类为我们提供了不错的选择。但是我仍然不明白 java 的创建者所说的“保持简单”是什么意思。
  • @TopGun743 如果一个参数既可以通过引用也可以通过值传递,那么对于程序员和编译器来说,这又是一种额外的复杂性。
【解决方案2】:

只有语言设计团队可以告诉你为什么,但我相信不允许“out”参数的原因可能是这样的:如果你想要一个计算两个东西的方法,你真正想要的是两个方法,或一种返回对象的方法。 这应该会带来更好的设计和更可维护的代码。

请注意,如果您真的想要“输出参数”,您可以轻松地使用一个元素的数组。例如:

void div(int a, int b, int[] q, int[] r) {
    if (q != null) q[0] = a/b;
    if (r != null) r[0] = a%b;
}

// elsewhere:
int[] quotient = new int[1];
int[] remainder = new int[1];
div(4, 3, quotient, remainder);

【讨论】:

    【解决方案3】:

    这只是我的观点,但我觉得 Java 的设计者相信他们可以通过消除功能而不是让它们更直观和更容易处理来简化编程。

    【讨论】:

      【解决方案4】:

      简短的回答是,这是一个设计决定,通过引用传递没有什么可以做,而通过值传递对象引用则无法做到。

      至于你的具体问题,有两种解决方案:

      一个可变的包装类:

      final class BooleanRef {
          public boolean value;
      }
      

      并将其用作:

      // Function
      void changeTheBoolean( BooleanRef b ){
          b.value = true;
      }
      
      // Call:
      BooleanRef b = new BooleanRef();
      changeTheBoolean( b );
      

      或者,(更hackish但更轻量级)包装在一个数组中:

      // Function
      void changeTheBoolean( boolean[] b ){
          b[0] = true;
      }
      
      // Call:
      boolean[] b = new boolean[1];
      changeTheBoolean( b );
      

      【讨论】:

        猜你喜欢
        • 2010-12-10
        • 1970-01-01
        • 1970-01-01
        • 2018-05-09
        • 2011-08-25
        • 1970-01-01
        • 2010-10-06
        • 2022-01-19
        • 1970-01-01
        相关资源
        最近更新 更多