我一直以为Java使用pass-by-reference. 但是,我读了一篇博客文章,声称Java使用pass-by-value. 我不认为我明白作者所做的区别。
什么是解释?
我一直以为Java使用pass-by-reference. 但是,我读了一篇博客文章,声称Java使用pass-by-value. 我不认为我明白作者所做的区别。
什么是解释?
当前回答
首先,我们应该明白什么是通过值或通过参考的意思。
通过值:方法参数值复制到另一个变量,然后复制的对象通过,这就是为什么它被称为通过值。
public class Balloon {
private String color;
public Balloon(){}
public Balloon(String c){
this.color=c;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
}
public class Test {
public static void main(String[] args) {
Balloon red = new Balloon("Red"); //memory reference 50
Balloon blue = new Balloon("Blue"); //memory reference 100
swap(red, blue);
System.out.println("red color="+red.getColor());
System.out.println("blue color="+blue.getColor());
foo(blue);
System.out.println("blue color="+blue.getColor());
}
private static void foo(Balloon balloon) { //baloon=100
balloon.setColor("Red"); //baloon=100
balloon = new Balloon("Green"); //baloon=200
balloon.setColor("Blue"); //baloon = 200
}
//Generic swap method
public static void swap(Object o1, Object o2){
Object temp = o1;
o1=o2;
o2=temp;
}
}
当我们执行上述程序时,我们会跟踪输出。
red color=Red
blue color=Blue
blue color=Red
Balloon red = new Balloon("Red");
Balloon blue = new Balloon("Blue");
public static void swap(Object o1, Object o2){ //o1=50, o2=100
Object temp = o1; //temp=50, o1=50, o2=100
o1=o2; //temp=50, o1=100, o2=100
o2=temp; //temp=50, o1=100, o2=50
} //method terminated
如果你已经明白了这一点,你可以轻松地理解混乱的原因. 因为变量只是对物体的参考,我们会感到困惑,我们正在通过参考,所以Java通过参考。
现在,让我们分析 foo() 方法执行。
private static void foo(Balloon balloon) { //baloon=100
balloon.setColor("Red"); //baloon=100
balloon = new Balloon("Green"); //baloon=200
balloon.setColor("Blue"); //baloon = 200
}
第一行是最重要的,当我们称之为一个方法时,该方法在参考位置上被称为对象,在这一点上,气球指向100,因此它的颜色变成红色。
其他回答
在我所知道的范围内,Java只知道值的呼叫,这意味着对于原始数据类型,您将使用复印件工作,对于对象,您将使用对象的参考复印件工作。
public static void swap(StringBuffer s1, StringBuffer s2) {
StringBuffer temp = s1;
s1 = s2;
s2 = temp;
}
public static void main(String[] args) {
StringBuffer s1 = new StringBuffer("Hello");
StringBuffer s2 = new StringBuffer("World");
swap(s1, s2);
System.out.println(s1);
System.out.println(s2);
}
这将人口Hello World而不是World Hello,因为在交换函数中,您使用复印件,这些复印件不会对主要的参考产生影响。
public static void appendWorld(StringBuffer s1) {
s1.append(" World");
}
public static void main(String[] args) {
StringBuffer s = new StringBuffer("Hello");
appendWorld(s);
System.out.println(s);
}
如果您将 StringBuffer 更改为 String,它只会产生 Hello 因为 String 是不可变的。
public static void appendWorld(String s){
s = s+" World";
}
public static void main(String[] args) {
String s = new String("Hello");
appendWorld(s);
System.out.println(s);
}
但是,你可以为 String 做一个插槽,这将使它能够与 Strings 一起使用:
class StringWrapper {
public String value;
public StringWrapper(String value) {
this.value = value;
}
}
public static void appendWorld(StringWrapper s){
s.value = s.value +" World";
}
public static void main(String[] args) {
StringWrapper s = new StringWrapper("Hello");
appendWorld(s);
System.out.println(s.value);
}
编辑:我认为这也是使用 StringBuffer 的理由,当涉及到“添加”两个线条时,因为你可以修改原始对象,你不能用像 String 这样的不可变的对象。
我做了这个小图表,显示了数据是如何创建和通过的
此分類上一篇
注意:原始值作为值传递,该值的第一个参考是方法的论点。
这意味着:
您可以在函数内更改 myObject 的值 但您不能更改 myObject 引用到,函数内,因为点不是 myObject 记住,点和 myObject 是引用,不同引用,但是,这些引用在同一个新点(0,0)
Java 仅通过值,没有通过参考,例如,您可以看到下面的示例。
package com.asok.cop.example.task;
public class Example {
int data = 50;
void change(int data) {
data = data + 100;// changes will be in the local variable
System.out.println("after add " + data);
}
public static void main(String args[]) {
Example op = new Example();
System.out.println("before change " + op.data);
op.change(500);
System.out.println("after change " + op.data);
}
}
出口:
before change 50
after add 600
after change 50
正如迈克尔在评论中所说:
物品仍然通过价值,尽管它们的操作表现像通过参考。 考虑无变 人物(人){人 = 新人(); } 呼叫者对个人对象的参考将保持不变. 物品本身通过价值,但其成员可以受到变化的影响。 为了成为真实的通过参考,我们必须能够重新分配论点到一个
不要重复,但对于那些在阅读许多答案后仍然可能会感到困惑的人来说,有一点:
通过值在Java是不等于通过值在C++,虽然听起来像这样,这可能是为什么有混乱。
打破它:
通过值在 C++ 意味着通过对象的值(如果对象),字面上,对象的副本通过值在 Java 意味着通过对象的地址值(如果对象),而不是真正的对象的“值”(一个副本)如 C++ 通过值在 Java,在一个对象(例如 myObj.setName(“新”)在一个函数内运作的对象(例如 myObj.setName(“新”)在函数之外对对象产生影响;通过通过函数的值。
所以,朋友们,一切都只是关于术语定义的差异(通过语言),你只需要知道它是如何工作的(也许有时有点混淆它是如何称之为我承认)!
Java 总是通过值的参数. Java 中的所有对象参考都通过值. 这意味着将值的副本转移到一个方法. 但技巧是通过值的副本也会改变对象的实际值。
请参见下面的例子,
public class ObjectReferenceExample {
public static void main(String... doYourBest) {
Student student = new Student();
transformIntoHomer(student);
System.out.println(student.name);
}
static void transformIntoDuleepa(Student student) {
student.name = "Duleepa";
}
}
class Student {
String name;
}
在此情况下,它将是Duleepa! 原因是Java对象变量只是指在记忆中真正的对象的参考。 因此,即使Java通过值的参数到方法,如果变量点到对象的参考,实际对象也会被更改。