我一直以为Java使用pass-by-reference. 但是,我读了一篇博客文章,声称Java使用pass-by-value. 我不认为我明白作者所做的区别。
什么是解释?
我一直以为Java使用pass-by-reference. 但是,我读了一篇博客文章,声称Java使用pass-by-value. 我不认为我明白作者所做的区别。
什么是解释?
当前回答
经过全面的讨论,我认为现在是时候将所有严重的结果聚集在一起。
/**
*
* @author Sam Ginrich
*
* All Rights Reserved!
*
*/
public class JavaIsPassByValue
{
static class SomeClass
{
int someValue;
public SomeClass(int someValue)
{
this.someValue = someValue;
}
}
static void passReferenceByValue(SomeClass someObject)
{
if (someObject == null)
{
throw new NullPointerException(
"This Object Reference was passed by Value,\r\n that's why you don't get a value from it.");
}
someObject.someValue = 49;
}
public static void main(String[] args)
{
SomeClass someObject = new SomeClass(27);
System.out.println("Here is the original value: " + someObject.someValue);
passReferenceByValue(someObject);
System.out.println(
"\nAs ´Java is pass by value´,\r\n everything without exception is passed by value\r\n and so an object's attribute cannot change: "
+ someObject.someValue);
System.out.println();
passReferenceByValue(null);
}
) )
从输出中可以很容易地看到,在Java中,一切都通过价值,如此简单!
Here is the original value: 27
As ´Java is pass by value´,
everything without exception is passed by value
and so an object´s attribute cannot change: 49
'Exception in thread "main" java.lang.NullPointerException: This Object Reference was passed by value,
that´s why you don´t get a value from it.
at JavaIsPassByValue.passReferenceByValue(JavaIsPassByValue.java:26)
at JavaIsPassByValue.main(JavaIsPassByValue.java:43)
其他回答
当涉及到对象时,对象本身不能转移到方法,所以我们通过对象的参考(地址)我们可以使用这个参考来操纵原始对象。
Account account1 = new Account();
此分類上一篇
如果我们将 array1 参考变量的值转换为反向Array 方法的论点,则在该方法中创建一个参考变量,而该参考变量则开始指向相同的序列(a)。
public class Test
{
public static void reverseArray(int[] array1)
{
// ...
}
public static void main(String[] args)
{
int[] array1 = { 1, 10, -7 };
int[] array2 = { 5, -190, 0 };
reverseArray(array1);
}
}
此分類上一篇
所以,如果我们说
array1[0] = 5;
我们有另一个参考变量在逆Array 方法(array2) 指向一个 array c. 如果我们要说
array1 = array2;
如果我们返回参考变量序列2作为逆序列方法的返回值,并将此值归咎于参考变量序列1在主要方法,序列1在主要将开始指向序列c。
public class Test
{
public static int[] reverseArray(int[] array1)
{
int[] array2 = { -7, 0, -1 };
array1[0] = 5; // array a becomes 5, 10, -7
array1 = array2; /* array1 of reverseArray starts
pointing to c instead of a (not shown in image below) */
return array2;
}
public static void main(String[] args)
{
int[] array1 = { 1, 10, -7 };
int[] array2 = { 5, -190, 0 };
array1 = reverseArray(array1); /* array1 of
main starts pointing to c instead of a */
}
}
此分類上一篇
与某些其他语言不同,Java不允许您在 pass-by-value 和 pass-by-reference 之间选择。
所有论点都以价值为准。
一个方法通话可以通过两个类型的 valuesto 一个方法
原始值的副本(例如,类型值 int 和双值)对物体的参考副本。
当一个方法改变原始类型参数时,参数的变化不会影响呼叫方法的原始论点值。
如果你修改一个参考类型参数以便它指向另一个对象,只有参数指向新对象 - 呼叫器的变量中存储的参数仍然指向原始对象。
参考: JavaTM 如何编程(早期对象),第十版
“pass-by-value”和“pass-by-reference”是指变量;“pass-by-value”是指变量的值转移到函数/方法;“pass-by-reference”是指该变量的参考转移到函数;“pass-by-reference”是指变量的值转移到函数;“pass-by-reference”是指变量的值转移到函数。
它如同这样:
public static void main(String[] args) {
Dog aDog = new Dog("Max");
Dog oldDog = aDog;
// we pass the object to foo
foo(aDog);
// aDog variable is still pointing to the "Max" dog when foo(...) returns
aDog.getName().equals("Max"); // true
aDog.getName().equals("Fifi"); // false
aDog == oldDog; // true
}
public static void foo(Dog d) {
d.getName().equals("Max"); // true
// change d inside of foo() to point to a new Dog instance "Fifi"
d = new Dog("Fifi");
d.getName().equals("Fifi"); // true
}
同样:
public static void main(String[] args) {
Dog aDog = new Dog("Max");
Dog oldDog = aDog;
foo(aDog);
// when foo(...) returns, the name of the dog has been changed to "Fifi"
aDog.getName().equals("Fifi"); // true
// but it is still the same dog:
aDog == oldDog; // true
}
public static void foo(Dog d) {
d.getName().equals("Max"); // true
// this changes the name of d to be "Fifi"
d.setName("Fifi");
}
有关参考通行和值通行的更多信息,请参见以下答案: https://stackoverflow.com/a/430958/6005228. 这更详细地解释了两者背后的语法和历史,并解释了为什么Java和许多其他现代语言似乎在某些情况下都会做两件事。
对某些文章进行一些修正。
C 不支持通过参考,它总是通过值,C++ 支持通过参考,但不是默认情况,而且非常危险。
无论是什么值在Java:原始或地址(大约)的对象,它总是通过值。
如果一个Java对象“行事”,就像它是通过参考一样,这是一种可变性属性,与过渡机制毫无关系。
我不确定为什么这那么令人困惑,尤其是因为这么多Java“编程师”没有正式训练,因此不明白真正发生在记忆中的事情吗?
查看此代码. 此代码不会扔 NullPointerException... 它将打印“Vinay”
public class Main {
public static void main(String[] args) {
String temp = "Vinay";
print(temp);
System.err.println(temp);
}
private static void print(String temp) {
temp = null;
}
}
如果 Java 通过参考,则应该将 NullPointerException 扔下来,因为参考设置为 Null。