我一直以为Java使用pass-by-reference. 但是,我读了一篇博客文章,声称Java使用pass-by-value. 我不认为我明白作者所做的区别。
什么是解释?
我一直以为Java使用pass-by-reference. 但是,我读了一篇博客文章,声称Java使用pass-by-value. 我不认为我明白作者所做的区别。
什么是解释?
当前回答
public void foo(Object param)
{
// some code in foo...
}
public void bar()
{
Object obj = new Object();
foo(obj);
}
它是相同的......
public void bar()
{
Object obj = new Object();
Object param = obj;
// some code in foo...
}
不要考虑在这个讨论中不相关的站点。
你会遇到的最常见的运营商之一是简单的任务运营商“="......它将其右上的值归分为其左上的运营商: int cadence = 0; int speed = 0; int gear = 1; 这个运营商也可以用于对象归分对象参考。
很明显,这个运营商如何以两种不同的方式行动:分配值和分配参考;最后,当它是一个对象......第一,当它不是一个对象,即当它是一个原始的。
真相在代码中,让我们尝试一下:
public class AssignmentEvaluation
{
static public class MyInteger
{
public int value = 0;
}
static public void main(String[] args)
{
System.out.println("Assignment operator evaluation using two MyInteger objects named height and width\n");
MyInteger height = new MyInteger();
MyInteger width = new MyInteger();
System.out.println("[1] Assign distinct integers to height and width values");
height.value = 9;
width.value = 1;
System.out.println("-> height is " + height.value + " and width is " + width.value + ", we are different things! \n");
System.out.println("[2] Assign to height's value the width's value");
height.value = width.value;
System.out.println("-> height is " + height.value + " and width is " + width.value + ", are we the same thing now? \n");
System.out.println("[3] Assign to height's value an integer other than width's value");
height.value = 9;
System.out.println("-> height is " + height.value + " and width is " + width.value + ", we are different things yet! \n");
System.out.println("[4] Assign to height the width object");
height = width;
System.out.println("-> height is " + height.value + " and width is " + width.value + ", are we the same thing now? \n");
System.out.println("[5] Assign to height's value an integer other than width's value");
height.value = 9;
System.out.println("-> height is " + height.value + " and width is " + width.value + ", we are the same thing now! \n");
System.out.println("[6] Assign to height a new MyInteger and an integer other than width's value");
height = new MyInteger();
height.value = 1;
System.out.println("-> height is " + height.value + " and width is " + width.value + ", we are different things again! \n");
}
}
这就是我跑步的结果:
Assignment operator evaluation using two MyInteger objects named height and width [1] Assign distinct integers to height and width values -> height is 9 and width is 1, we are different things! [2] Assign to height's value the width's value -> height is 1 and width is 1, are we the same thing now? [3] Assign to height's value an integer other than width's value -> height is 9 and width is 1, we are different things yet! [4] Assign to height the width object -> height is 1 and width is 1, are we the same thing now? [5] Assign to height's value an integer other than width's value -> height is 9 and width is 9, we are the same thing now! [6] Assign to height a new MyInteger and an integer other than width's value -> height is 1 and width is 9, we are different things again!
我们不能那么确定,因为在 [6] 对象是相同的,然后我们将一个新的对象归分给其中一个,然后,对象有不同的价值! 他们现在如何区分,如果他们是相同的? 他们应该在这里也是相同的!!!
此操作员也可以用于对象分配对象参考。
其他回答
有这么多长的答案,让我给你一个简单的答案:
Java 总是按值传达一切,也就是说,参考也按值传达。
简而言之,您无法改变任何参数的值,但您可以通过对象参考的方法或属性更改。
Java 以值传输对象的参考。
它是原始值或参考值的副本,如果是原始值,它是价值的比特的副本,如果是对象,它是参考值的副本。
public class PassByCopy{
public static void changeName(Dog d){
d.name = "Fido";
}
public static void main(String[] args){
Dog d = new Dog("Maxx");
System.out.println("name= "+ d.name);
changeName(d);
System.out.println("name= "+ d.name);
}
}
class Dog{
public String name;
public Dog(String s){
this.name = s;
}
}
使用 Java PassByCopy:
名称= Maxx 名称= Fido
原始粘贴类和线条是不可变的,因此使用这些类型的任何例子都不会像其他类型/对象一样工作。
基本上,重新定义对象参数不会影响论点,例如,
private static void foo(Object bar) {
bar = null;
}
public static void main(String[] args) {
String baz = "Hah!";
foo(baz);
System.out.println(baz);
}
这个工作的原因是因为字符串是 baz 的值的副本,这只是“Hah!”的参考。如果它是实际的参考本身,那么 foo 会重新定义 baz 到 null。
讓我試圖用四個例子來解釋我的理解:Java是通過價值,而不是通過参考。
* * *
◎
public class PassByValueString {
public static void main(String[] args) {
new PassByValueString().caller();
}
public void caller() {
String value = "Nikhil";
boolean valueflag = false;
String output = method(value, valueflag);
/*
* 'output' is insignificant in this example. we are more interested in
* 'value' and 'valueflag'
*/
System.out.println("output : " + output);
System.out.println("value : " + value);
System.out.println("valueflag : " + valueflag);
}
public String method(String value, boolean valueflag) {
value = "Anand";
valueflag = true;
return "output";
}
}
output : output
value : Nikhil
valueflag : false
例子2:
/** * * Pass By 價值 */
public class PassByValueNewString {
public static void main(String[] args) {
new PassByValueNewString().caller();
}
public void caller() {
String value = new String("Nikhil");
boolean valueflag = false;
String output = method(value, valueflag);
/*
* 'output' is insignificant in this example. we are more interested in
* 'value' and 'valueflag'
*/
System.out.println("output : " + output);
System.out.println("value : " + value);
System.out.println("valueflag : " + valueflag);
}
public String method(String value, boolean valueflag) {
value = "Anand";
valueflag = true;
return "output";
}
}
output : output
value : Nikhil
valueflag : false
/** 这个“通过价值”具有“通过参考”的感觉
但是,从这个例子,我们可以理解,它只是通过值,记住,在这里我们通过参考作为值. 也就是说:参考通过值. 这就是为什么它们可以改变,但它仍然保持在当地范围后真实。
public class PassByValueObjectCase1 {
private class Student {
int id;
String name;
public Student() {
}
public Student(int id, String name) {
super();
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student [id=" + id + ", name=" + name + "]";
}
}
public static void main(String[] args) {
new PassByValueObjectCase1().caller();
}
public void caller() {
Student student = new Student(10, "Nikhil");
String output = method(student);
/*
* 'output' is insignificant in this example. we are more interested in
* 'student'
*/
System.out.println("output : " + output);
System.out.println("student : " + student);
}
public String method(Student student) {
student.setName("Anand");
return "output";
}
}
结果
output : output
student : Student [id=10, name=Anand]
例子4:
* * *
除了在Example3(PassByValueObjectCase1.java)中提到的外,我们不能在原始范围之外更改实际参考。
注意: 我不符合私人课堂学生的代码. 学生的课堂定义与例子3相同。
◎
public class PassByValueObjectCase2 {
public static void main(String[] args) {
new PassByValueObjectCase2().caller();
}
public void caller() {
// student has the actual reference to a Student object created
// can we change this actual reference outside the local scope? Let's see
Student student = new Student(10, "Nikhil");
String output = method(student);
/*
* 'output' is insignificant in this example. we are more interested in
* 'student'
*/
System.out.println("output : " + output);
System.out.println("student : " + student); // Will it print Nikhil or Anand?
}
public String method(Student student) {
student = new Student(20, "Anand");
return "output";
}
}
output : output
student : Student [id=10, name=Nikhil]