Java中数组是按值传递还是按引用传递? [英] Are arrays passed by value or passed by reference in Java?

查看:30
本文介绍了Java中数组是按值传递还是按引用传递?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

数组不是 Java 中的原始类型,而是它们也不是对象,所以是它们是按值传递还是按引用传递?它是否取决于数组包含的内容,例如引用或原始类型?

Arrays are not a primitive type in Java, but they are not objects either, so are they passed by value or by reference? Does it depend on what the array contains, for example references or a primitive type?

推荐答案

您的问题基于错误的前提.

Your question is based on a false premise.

数组不是 Java 中的原始类型,但它们也不是对象......

事实上,Java 中的所有数组都是对象1.每个 Java 数组类型都有 java.lang.Object 作为其超类型,并继承了 Object API 中所有方法的实现.

In fact, all arrays in Java are objects1. Every Java array type has java.lang.Object as its supertype, and inherits the implementation of all methods in the Object API.

... 那么它们是按值传递还是按引用传递?它是否取决于数组包含的内容,例如引用或原始类型?

... so are they passed by value or by reference? Does it depend on what the array contains, for example references or a primitive type?

简短回答:1) 按值传递,2) 没有区别.

Short answers: 1) pass by value, and 2) it makes no difference.

更长的答案:

与所有 Java 对象一样,数组是按值传递的……但值是对数组的引用.所以,当你在被调用的方法中为数组的一个单元格赋值时,你将赋值给调用者看到的同一个数组对象.

Like all Java objects, arrays are passed by value ... but the value is the reference to the array. So, when you assign something to a cell of the array in the called method, you will be assigning to the same array object that the caller sees.

这不是传递引用.真实传递引用涉及传递变量的地址.使用real 传递引用,被调用的方法可以赋值给它的局部变量,这会导致调用者中的变量被更新.

This is NOT pass-by-reference. Real pass-by-reference involves passing the address of a variable. With real pass-by-reference, the called method can assign to its local variable, and this causes the variable in the caller to be updated.

但不是在 Java 中.在Java中,被调用的方法可以更新数组的内容,也可以更新其数组引用的副本,但不能更新调用者中保存调用者数组引用的变量.因此……Java 提供的不是传递引用.

But not in Java. In Java, the called method can update the contents of the array, and it can update its copy of the array reference, but it can't update the variable in the caller that holds the caller's array reference. Hence ... what Java is providing is NOT pass-by-reference.

这里有一些链接解释了引用传递和值传递之间的区别.如果您不理解我上面的解释,或者您倾向于不同意这些术语,则应该阅读它们.

Here are some links that explain the difference between pass-by-reference and pass-by-value. If you don't understand my explanations above, or if you feel inclined to disagree with the terminology, you should read them.

相关的 SO 问题:

历史背景:

短语pass-by-reference"原本是call-by-reference",用来区分FORTRAN(call-by-reference)和ALGOL-60(call-by-reference)的参数传递语义按值和按名称调用).

The phrase "pass-by-reference" was originally "call-by-reference", and it was used to distinguish the argument passing semantics of FORTRAN (call-by-reference) from those of ALGOL-60 (call-by-value and call-by-name).

  • 在按值调用中,参数表达式被计算为一个值,然后将该值复制到被调用的方法中.

  • In call-by-value, the argument expression is evaluated to a value, and that value is copied to the called method.

在按引用调用中,参数表达式被部分评估为传递给调用方法的左值"(即变量或数组元素的地址).然后调用方法可以直接读取和更新变量/元素.

In call-by-reference, the argument expression is partially evaluated to an "lvalue" (i.e. the address of a variable or array element) that is passed to the calling method. The calling method can then directly read and update the variable / element.

在 call-by-name 中,实际参数表达式被传递给调用方法 (!!),它可以多次计算它 (!!!).这实现起来很复杂,并且可能被用来(滥用)来编写非常难以理解的代码.Call-by-name 只在 Algol-60 中使用过(谢天谢地!).

In call-by-name, the actual argument expression is passed to the calling method (!!) which can evaluate it multiple times (!!!). This was complicated to implement, and could be used (abused) to write code that was very difficult to understand. Call-by-name was only ever used in Algol-60 (thankfully!).

更新

实际上,Algol-60 的按名称调用类似于将 lambda 表达式作为参数传递.问题在于这些不完全是 lambda 表达式(它们在实现级别被称为thunk")可以间接修改调用过程/函数中范围内变量的状态.这是使他们如此难以理解的部分原因.(例如,请参阅 Jensen 的设备 上的维基百科页面.)

Actually, Algol-60's call-by-name is similar to passing lambda expressions as parameters. The wrinkle is that these not-exactly-lambda-expressions (they were referred to as "thunks" at the implementation level) can indirectly modify the state of variables that are in scope in the calling procedure / function. That is part of what made them so hard to understand. (See the Wikipedia page on Jensen's Device for example.)

1.链接的问答中没有任何内容(Java 中的数组和它们如何存储在内存中) 要么声明要么暗示数组不是对象.

1. Nothing in the linked Q&A (Arrays in Java and how they are stored in memory) either states or implies that arrays are not objects.

这篇关于Java中数组是按值传递还是按引用传递?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆