java 中的按值传递问题
Issue with pass by value in java
Java 支持按值传递(总是在副本上工作)但是当你传递一个用户定义的对象时它会改变实际的对象(一种按引用传递但没有指针改变),我理解但为什么下面的 changeObject2CLEAR 方法实际上改变了对象的值?相反,它必须在副本上工作?
import java.util.HashMap;
import java.util.Map;
public class PassBy {
class CustomBean {
public CustomBean() {
}
private int id;
private String 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 id + ", " + name;
}
}
public Map<Integer, String> changeObject2NULL (Map<Integer, String> m) {
m = null;
return m;
}
public Map<Integer, String> changeObject2CLEAR (Map<Integer, String> m) {
m.clear();
return m;
}
public CustomBean changeCustomObject (CustomBean _e) {
_e.setId(_e.getId() + 1);
return _e;
}
public static void main(String[] args) {
PassBy passby = new PassBy();
Map<Integer, String> map = new HashMap<Integer, String>();
map.put(1, "value");
CustomBean bean = passby.new CustomBean();
bean.setId(1);
bean.setName("arun");
// Initial Value
System.out.println(map.toString());
System.out.println(bean.toString());
System.out.println("-------------------------");
// Pass by value works fine
passby.changeObject2NULL(map);
passby.changeCustomObject(bean);
// Custom object value changes since we pass as the object reference but Map remains with actual value
System.out.println(map.toString());
System.out.println(bean.toString());
System.out.println("-------------------------");
// Testing Pass by value - CANT UNDERSTAND why it changed the object since it has to be pass-by-value and not by ref in this case ??
// Why setting to null not chainging the value but clear does ?
passby.changeObject2CLEAR(map);
System.out.println(map.toString());
}
}
AFAIK Java 仅按值传递,但值实际上是引用
所以让我试着帮助您理解,Java 总是按值传递,但我相信您知道所有对象实例实际上都是指向这些对象的指针。现在当你发送一个对象时,你传递的是对象地址的值。如果您对对象本身做了任何更改(如 m.clear()),那么它会转到该地址,对对象进行类型转换并对其执行操作。但是如果你改变指针本身,比如m = null,那么只有你持有的地址副本被改变。
当你打电话时 changeObject2CLEAR
passby.changeObject2CLEAR(map);
您正在传递实例 map
。
方法中changeObject2CLEAR
public Map<Integer, String> changeObject2CLEAR (Map<Integer, String> m) {
m.clear();
return m;
}
您在同一实例 map
上执行 .clear()
,即使在方法中它被称为 m
。
作为理解练习,请注意以下方法将做同样的事情。
public void changeObject2CLEAR (Map<Integer, String> m) {
m.clear();
}
请注意,您不必 return Map<Integer, String> m
,因为您有权访问的 map
是在调用该方法的任何地方传入的同一个实例对象。
编辑:为什么 m = null;
表现为按值传递而 m.clear()
表现为按引用传递?
当您 'assign' 将值 null
更改为 m
时,您正在将引用从先前的实例对象 map
更改为新的内存位置 null
.
当您在实例对象 m
上调用 .clear()
方法时,您是在 map
引用的内存位置的同一对象上调用该方法,因此您修改了map
对象。
Java 支持按值传递(总是在副本上工作)但是当你传递一个用户定义的对象时它会改变实际的对象(一种按引用传递但没有指针改变),我理解但为什么下面的 changeObject2CLEAR 方法实际上改变了对象的值?相反,它必须在副本上工作?
import java.util.HashMap;
import java.util.Map;
public class PassBy {
class CustomBean {
public CustomBean() {
}
private int id;
private String 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 id + ", " + name;
}
}
public Map<Integer, String> changeObject2NULL (Map<Integer, String> m) {
m = null;
return m;
}
public Map<Integer, String> changeObject2CLEAR (Map<Integer, String> m) {
m.clear();
return m;
}
public CustomBean changeCustomObject (CustomBean _e) {
_e.setId(_e.getId() + 1);
return _e;
}
public static void main(String[] args) {
PassBy passby = new PassBy();
Map<Integer, String> map = new HashMap<Integer, String>();
map.put(1, "value");
CustomBean bean = passby.new CustomBean();
bean.setId(1);
bean.setName("arun");
// Initial Value
System.out.println(map.toString());
System.out.println(bean.toString());
System.out.println("-------------------------");
// Pass by value works fine
passby.changeObject2NULL(map);
passby.changeCustomObject(bean);
// Custom object value changes since we pass as the object reference but Map remains with actual value
System.out.println(map.toString());
System.out.println(bean.toString());
System.out.println("-------------------------");
// Testing Pass by value - CANT UNDERSTAND why it changed the object since it has to be pass-by-value and not by ref in this case ??
// Why setting to null not chainging the value but clear does ?
passby.changeObject2CLEAR(map);
System.out.println(map.toString());
}
}
AFAIK Java 仅按值传递,但值实际上是引用
所以让我试着帮助您理解,Java 总是按值传递,但我相信您知道所有对象实例实际上都是指向这些对象的指针。现在当你发送一个对象时,你传递的是对象地址的值。如果您对对象本身做了任何更改(如 m.clear()),那么它会转到该地址,对对象进行类型转换并对其执行操作。但是如果你改变指针本身,比如m = null,那么只有你持有的地址副本被改变。
当你打电话时 changeObject2CLEAR
passby.changeObject2CLEAR(map);
您正在传递实例 map
。
方法中changeObject2CLEAR
public Map<Integer, String> changeObject2CLEAR (Map<Integer, String> m) {
m.clear();
return m;
}
您在同一实例 map
上执行 .clear()
,即使在方法中它被称为 m
。
作为理解练习,请注意以下方法将做同样的事情。
public void changeObject2CLEAR (Map<Integer, String> m) {
m.clear();
}
请注意,您不必 return Map<Integer, String> m
,因为您有权访问的 map
是在调用该方法的任何地方传入的同一个实例对象。
编辑:为什么 m = null;
表现为按值传递而 m.clear()
表现为按引用传递?
当您 'assign' 将值 null
更改为 m
时,您正在将引用从先前的实例对象 map
更改为新的内存位置 null
.
当您在实例对象 m
上调用 .clear()
方法时,您是在 map
引用的内存位置的同一对象上调用该方法,因此您修改了map
对象。