我一直以为Java使用pass-by-reference. 但是,我读了一篇博客文章,声称Java使用pass-by-value. 我不认为我明白作者所做的区别。
什么是解释?
我一直以为Java使用pass-by-reference. 但是,我读了一篇博客文章,声称Java使用pass-by-value. 我不认为我明白作者所做的区别。
什么是解释?
当前回答
我会以另一种方式说:
在 Java 引用中,这些引用是通过的(但不是对象),这些引用是通过的值(引用本身是复制的,你有 2 引用作为结果,你没有控制在方法中的第 1 引用下)。
例如,在Python相同的情况,但有文章,描述他们称之为Pass-by-reference,只有原因引用被使用。
其他回答
using namespace std;
#include <iostream>
void change (char *&str){ // the '&' makes this a reference parameter
str = NULL;
}
int main()
{
char *str = "not Null";
change(str);
cout<<"str is " << str; // ==>str is <null>
}
Java 通过值示例“一个 Java 参考”
public class ValueDemo{
public void change (String str){
str = null;
}
public static void main(String []args){
ValueDemo vd = new ValueDemo();
String str = "not null";
vd.change(str);
System.out.println("str is " + str); // ==> str is not null!!
// Note that if "str" was
// passed-by-reference, it
// WOULD BE NULL after the
// call to change().
}
}
编辑
program passByRefDemo;
type
iptr = ^integer;
var
ptr: iptr;
procedure setToNil(var ptr : iptr);
begin
ptr := nil;
end;
begin
new(ptr);
ptr^ := 10;
setToNil(ptr);
if (ptr = nil) then
writeln('ptr seems to be nil'); { ptr should be nil, so this line will run. }
end.
《Java编程语言》(The Java Programming Language)由Ken Arnold、James Gosling(Java的发明者)和David Holmes,第2章,第2节。
Java 编程语言不会通过对象的参考;它通过对象的参考的值. 因为两个副本的相同参考的参考相同的实际对象,通过一个参考变量进行的变化是可见的通过另一个。
这本书的部分有一个很好的解释,参数通过Java和区别通过参考和通过值之间的区别,这是由Java的创作者。
我希望这会解决讨论,但可能不会。
编辑3
通过参考值 - 参考的变化不在呼叫者的范围内反映,但对对象的变化是因为参考是复制的,但原始和复制都指同一个对象。
Java 始终是 pass-by-value,参数是经过的变量的副本,所有对象都是用参考来定义的,参考是存储一个记忆地址的变量,其中对象在记忆中。
查看评论以了解执行中发生了什么;跟随数字,因为它们显示执行的流动。
class Example
{
public static void test (Cat ref)
{
// 3 - <ref> is a copy of the reference <a>
// both currently reference Grumpy
System.out.println(ref.getName());
// 4 - now <ref> references a new <Cat> object named "Nyan"
ref = new Cat("Nyan");
// 5 - this should print "Nyan"
System.out.println( ref.getName() );
}
public static void main (String [] args)
{
// 1 - a is a <Cat> reference that references a Cat object in memory with name "Grumpy"
Cat a = new Cat("Grumpy");
// 2 - call to function test which takes a <Cat> reference
test (a);
// 6 - function call ends, and <ref> life-time ends
// "Nyan" object has no references and the Garbage
// Collector will remove it from memory when invoked
// 7 - this should print "Grumpy"
System.out.println(a.getName());
}
}
Java 是由價值通過的。
在某种程度上,我从来没有透露过原始数据类型和对象的值/参考。因此,我用下列代码来测试我的满意度和清晰度;可能有助于寻求类似清晰度的人:
class Test {
public static void main (String[] args) throws java.lang.Exception
{
// Primitive type
System.out.println("Primitve:");
int a = 5;
primitiveFunc(a);
System.out.println("Three: " + a); //5
//Object
System.out.println("Object:");
DummyObject dummyObject = new DummyObject();
System.out.println("One: " + dummyObject.getObj()); //555
objectFunc(dummyObject);
System.out.println("Four: " + dummyObject.getObj()); //666 (555 if line in method uncommented.)
}
private static void primitiveFunc(int b) {
System.out.println("One: " + b); //5
b = 10;
System.out.println("Two:" + b); //10
}
private static void objectFunc(DummyObject b) {
System.out.println("Two: " + b.getObj()); //555
//b = new DummyObject();
b.setObj(666);
System.out.println("Three:" + b.getObj()); //666
}
}
class DummyObject {
private int obj = 555;
public int getObj() { return obj; }
public void setObj(int num) { obj = num; }
}
如果行 b = 新 DummyObject() 没有评论,随后进行的修改是在一个新的对象,一个新的实例上进行的。 因此,它不反映在方法被召回的地方。 但是,否则,变化是反映的,因为修改只是在对象的“参考”上进行的,即 - b 点到相同的 dummyObject。
在这个条纹中的答案之一(https://stackoverflow.com/a/12429953/4233180)的描述可以帮助获得更深入的理解。
数据通过参数在函数之间共享,现在有两种方式通过参数:
通过参数 : 呼叫器和呼叫器使用相同的变量为参数. 通过值 : 呼叫器和呼叫器有两个独立的变量与相同的值。
Java 使用 Pass by Value
在传输原始数据时,它复制原始数据类型的值;在传输对象时,它复制对象的地址,并转移到转换方法变量。
Java 在存储变量中遵循以下规则:
原始和对象参考等本地变量在 Stack 记忆中创建,对象在 Heap 记忆中创建。
使用原始数据类型的例子:
public class PassByValuePrimitive {
public static void main(String[] args) {
int i=5;
System.out.println(i); //prints 5
change(i);
System.out.println(i); //prints 5
}
private static void change(int i) {
System.out.println(i); //prints 5
i=10;
System.out.println(i); //prints 10
}
}
使用对象的例子:
public class PassByValueObject {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("prem");
list.add("raj");
new PassByValueObject().change(list);
System.out.println(list); // prints [prem, raj, ram]
}
private void change(List list) {
System.out.println(list.get(0)); // prem
list.add("ram");
list=null;
System.out.println(list.add("bheem")); //gets NullPointerException
}
}
Java 通过原始类型为值和类型为参考
现在,人们喜欢无限地争论是否“通过参考”是正确的方式来描述Java et al. 实际上做什么。
通过一个对象不会复制对象,转移到函数的对象可以由函数修改其成员,转移到函数的原始值不能由函数修改。
在我的书中,它被称为通过参考。
布莱恩·比(Brian Bi) - 哪种编程语言通过参考?