我一直以为Java使用pass-by-reference. 但是,我读了一篇博客文章,声称Java使用pass-by-value. 我不认为我明白作者所做的区别。
什么是解释?
我一直以为Java使用pass-by-reference. 但是,我读了一篇博客文章,声称Java使用pass-by-value. 我不认为我明白作者所做的区别。
什么是解释?
当前回答
真的很简单,真的很简单:
对于原始类型的变量(如 int、boolean、char 等),当您使用其名称为方法论时,您将其中的值(5、 true、c)传输。
对于参考类型的变量(例如,线条,对象等),当您使用其名称为方法论时,您将其中的值转移(对象“点”的参考值)。这个参考值被“复制”,而变量在方法引用后仍然保持其值。
不管怎样,你总是通过价值的东西。
比较这个说 C++ 你可以有一个方法来采取一个 int& 或在 C# 你可以采取一个 ref int (虽然,在这种情况下,你也必须使用 ref 修改器,当将变量的名称转移到方法。
其他回答
Java 总是通过价值,没有例外,永远。
因此,怎样才能让任何人完全困惑,相信Java是通过参考,或者认为他们有一个Java作为通过参考的例子?关键点是Java从来没有提供直接访问对象本身的价值,在任何情况下。
因此,当呼叫一种方法时
对于原始论点(int、long等)而言,值的过渡是原始的实际价值(例如,3)。
所以,如果你有DoSomething(foo)和公共空白DoSomething(Foo foo) {.. } 两个 Foos 有复制的参考,指向相同的对象。
当然,通过值对一个对象的参考看起来非常相似(并且在实践中不可分辨的)通过对象的参考。
Java,当然,毫无疑问,是“通过价值”。 此外,由于Java是(主要)对象导向和对象与参考工作,它很容易被困惑,并认为它是“通过参考”
但要测试它是否真的通过值或通过参考,你可以使用原始类型和参考:
@Test
public void sampleTest(){
int i = 5;
incrementBy100(i);
System.out.println("passed ==> "+ i);
Integer j = new Integer(5);
incrementBy100(j);
System.out.println("passed ==> "+ j);
}
/**
* @param i
*/
private void incrementBy100(int i) {
i += 100;
System.out.println("incremented = "+ i);
}
产量是:
incremented = 105
passed ==> 5
incremented = 105
passed ==> 5
因此,在两种情况下,任何在方法中发生的事情都不会改变真正的对象,因为对象的价值已经过去了,而不是对象本身的参考。
但是,当你将自定义对象转移到一种方法,而一种方法并改变它时,它也会改变真正的对象,因为即使你通过了对象,你也将其参考作为一种价值转移到一种方法。
@Test
public void sampleTest2(){
Person person = new Person(24, "John");
System.out.println(person);
alterPerson(person);
System.out.println(person);
}
/**
* @param person
*/
private void alterPerson(Person person) {
person.setAge(45);
Person altered = person;
altered.setName("Tom");
}
private static class Person{
private int age;
private String name;
public Person(int age, String name) {
this.age=age;
this.name =name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("Person [age=");
builder.append(age);
builder.append(", name=");
builder.append(name);
builder.append("]");
return builder.toString();
}
}
在这种情况下,产量是:
Person [age=24, name=John]
Person [age=45, name=Tom]
Java 总是使用 Call by Value. 这意味着该方法获得所有参数值的副本。
考虑下列三种情况:
1、试图改变原始变量
public static void increment(int x) { x++; }
int a = 3;
increment(a);
x 将复制一个值,并将增加 x,一个将保持相同的值
(二)试图改变对象的原始领域
public static void increment(Person p) { p.age++; }
Person pers = new Person(20); // age = 20
increment(pers);
p 将复制个体的参考值,并将增加年龄领域,变量是指相同的对象,所以年龄改变。
(三)试图改变参考变量的参考值
public static void swap(Person p1, Person p2) {
Person temp = p1;
p1 = p2;
p2 = temp;
}
Person pers1 = new Person(10);
Person pers2 = new Person(20);
swap(pers1, pers2);
呼叫交换 p1 后,p2 复制 pers1 和 pers2 的参考值与值交换,因此 pers1 和 pers2 仍然相同。
因此,您只能在将参考值复制到该对象时更改对象的字段。
我觉得关于“pass-by-reference vs pass-by-value”的争论并不太有用。
在我们到达Java实施之前,滑板/滑板上走路:价值观以顺序的方式滑板上走路,就像一家咖啡馆里的滑板一样。 滑板中的记忆(也称为动态记忆)是危险的,不组织的。
好吧! 首先,地方原始人走在地板上,所以这个代码:
int x = 3;
float y = 101.1f;
boolean amIAwesome = true;
此分類上一篇
当你宣布和即时一个对象时,实际对象会走在地板上,什么会走在地板上?对象的地址会走在地板上,C++程序员会称之为指标,但一些Java开发人员反对“指标”这个词。
像这样:
int problems = 99;
String name = "Jay-Z";
此分類上一篇
JButton[] marxBros = new JButton[3];
marxBros[0] = new JButton("Groucho");
marxBros[1] = new JButton("Zeppo");
marxBros[2] = new JButton("Harpo");
此分類上一篇
private static void shout(String name){
System.out.println("There goes " + name + "!");
}
public static void main(String[] args){
String hisName = "John J. Jingleheimerschmitz";
String myName = hisName;
shout(myName);
}
此分類上一篇
所以,值,参考?你说“土豆”。
我试图简化上面的例子,只保持问题的本质. 让我把这个作为一个容易记住和正确应用的故事。 故事如下: 你有一个宠物狗,吉米,尾巴长12英寸。
下次你旅行,你带狗,无意中,到一个邪恶的<unk>子,他也是长尾的仇恨者,所以他把它切到一个可怜的2英寸,但他这样做你的亲爱的吉米,而不是一个克隆。
public class Doggie {
public static void main(String...args) {
System.out.println("At the owner's home:");
Dog d = new Dog(12);
d.wag();
goodVet(d);
System.out.println("With the owner again:)");
d.wag();
badVet(d);
System.out.println("With the owner again(:");
d.wag();
}
public static void goodVet (Dog dog) {
System.out.println("At the good vet:");
dog.wag();
dog = new Dog(12); // create a clone
dog.cutTail(6); // cut the clone's tail
dog.wag();
}
public static void badVet (Dog dog) {
System.out.println("At the bad vet:");
dog.wag();
dog.cutTail(2); // cut the original dog's tail
dog.wag();
}
}
class Dog {
int tailLength;
public Dog(int originalLength) {
this.tailLength = originalLength;
}
public void cutTail (int newLength) {
this.tailLength = newLength;
}
public void wag() {
System.out.println("Wagging my " +tailLength +" inch tail");
}
}
Output:
At the owner's home:
Wagging my 12 inch tail
At the good vet:
Wagging my 12 inch tail
Wagging my 6 inch tail
With the owner again:)
Wagging my 12 inch tail
At the bad vet:
Wagging my 12 inch tail
Wagging my 2 inch tail
With the owner again(:
Wagging my 2 inch tail