当前位置:  开发笔记 > 编程语言 > 正文

有人可以向我解释在Java中传递"值"而不是"引用"背后的原因是什么?

如何解决《有人可以向我解释在Java中传递"值"而不是"引用"背后的原因是什么?》经验,为你挑选了3个好方法。

我是Java的新手(多年来一直在写其他东西),除非我遗漏了一些东西(我很高兴在这里错了)以下是一个致命的缺陷......

String foo = new String();
thisDoesntWork(foo);
System.out.println(foo);//this prints nothing

public static void thisDoesntWork(String foo){
   foo = "howdy";
}

现在,我很清楚(相当差的措辞)概念,在java中,一切都是通过"值"而不是"引用"传递的,但String是一个对象,有各种各样的花里胡哨,所以,人们会期待与int不同,用户可以对传递给方法的东西进行操作(并且不会被overloaded =设置的值所困).

有人可以向我解释这个设计选择背后的原因是什么?正如我所说,我不是想在这里,也许我错过了一些明显的东西?



1> Ric Tokyo..:

这个咆哮解释得比我甚至尝试过:

在Java中,原语按值传递.但是,对象不通过引用传递.正确的语句是对象引用按值传递.


很高兴你喜欢我的咆哮;)

2> Dave Markle..:

当你传递"foo"时,你将对"foo" 的引用作为值传递给ThisDoesntWork().这意味着当您在方法内部执行"foo"赋值时,您只需将局部变量(foo)的引用设置为对新字符串的引用.

在考虑字符串在Java中的行为方式时要记住的另一件事是字符串是不可变的.它在C#中的工作方式相同,并且有一些很好的理由:

安全性:如果没有人可以修改数据,没有人可以将数据插入到您的字符串中并导致缓冲区溢出错误!

速度:如果您可以确定您的字符串是不可变的,那么您知道它的大小始终是相同的,并且您在操作它时不必在内存中移动数据结构.您(语言设计者)也不必担心将String实现为慢速链接列表.但这会削减两种方式.仅使用+运算符追加字符串可能是内存昂贵的,并且您必须使用StringBuilder对象以高性能,内存有效的方式执行此操作.

现在谈谈你更大的问题.为什么对象以这种方式传递?好吧,如果Java传递你的字符串就像你传统上所说的"按值",它必须实际复制整个字符串,然后再传递给你的函数.那很慢.如果它通过引用传递字符串并让你改变它(就像C一样),你就会遇到我刚刚列出的问题.


@Axelle:你错过了"通过引用传递"的含义.Java*会按值传递参数.如果它具有传递参考,则效果将非常不同.您需要了解传递引用的真正含义.它与"按值传递引用"不同.

3> Laplie Ander..:

由于我的原始答案是"为什么会发生",而不是"为什么设计的语言如此发生",我会再给它一个.

为简化起见,我将摆脱方法调用并以另一种方式显示正在发生的事情.

String a = "hello";
String b = a;
String b = "howdy"

System.out.print(a) //prints hello

为了得到最后的语句来输出"hello",b必须指向内存中的同一个"洞"是一个点(指针).当你想通过引用传递时,这就是你想要的.Java决定不去这个方向有几个原因:

指针令人困惑 Java的设计者试图删除一些关于其他语言的更令人困惑的事情.指针是C/C++最容易被误解和使用不当的结构之一,还有运算符重载.

指针是安全风险指针在误用时会导致许多安全问题.恶意程序会将内容分配给内存的那一部分,然后您认为您的对象实际上是其他人的内容.(Java已经摆脱了最大的安全问题,缓冲区溢出,带有已检查的数组)

抽象泄漏当你开始处理"内存中的内容和位置"时,你的抽象变得不那么抽象了.虽然抽象泄漏几乎肯定会侵入一种语言,但设计师并不想直接烘焙它.

对象都是你关心的 在Java中,一切都是对象,而不是对象所占据的空间.添加指针会使空间占据重要的对象,尽管.......

您可以通过创建"Hole"对象来模拟您想要的内容.您甚至可以使用泛型使其类型安全.例如:

public class Hole {
   private T objectInHole;

   public void putInHole(T object) {
      this.objectInHole = object;
   }
   public T getOutOfHole() {
      return objectInHole;
   }

   public String toString() {
      return objectInHole.toString();
   }
   .....equals, hashCode, etc.
}


Hole foo = new Hole foo){
   foo.putInHole("howdy");
}

推荐阅读
和谐啄木鸟
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有