传递的是值的副本。方法中对副本的修改,不会影响到调用方,也就是不会影响原来的值;
传递的是引用的副本,共用一个内存,会影响到调用方。此时,形参和实参指向同一个内存地址。
但是对引用副本本身(对象地址)的修改,如设置为null,重新指向其他对象,不会影响到调用方。
/**
* 基本数据类型
*/
@Test
public void test2(){
int value = 1;
log.info("当前值:{}",value);
change(value);
log.info("最终值:{}",value);
}
private void change(int value) {
value = 100*value;
}
执行结果
当前值:1
最终值:1
总结
从输出的的结果中可以看到原本的value并没有被修改,即传值传递的是值的副本,不会影响到本身。
对象
package com.kang.webservice.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Integer id;
private String userId;
private String userName;
}
/**
* 引用数据类型
*/
@Test
public void test3(){
log.info("=========================对象================================");
User user = new User(4, "tom", "汤姆");
log.info("当前值:{}",user);
changeObject(user);
log.info("最终值:{}",user);
log.info("=========================数组================================");
List list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
log.info("当前值:{}",JSON.toJSONString(list));
changeList(list);
log.info("最终值:{}",JSON.toJSONString(list));
log.info("=========================Map================================");
Map map = new HashMap<>();
map.put("user",new User(2,"66","测试01"));
log.info("当前值:{}",JSON.toJSONString(map));
changeMap(map);
log.info("最终值:{}",JSON.toJSONString(map));
}
private void changeMap(Map map) {
User user = map.get("user");
user.setUserId("没有赎金惨遭撕票");
}
private void changeList(List list) {
list.remove(1);
list.add(5);
}
private void changeObject(User user) {
user.setUserId("我被不发份子绑票了");
}
执行结果
14:44:41.149 [main] INFO com.kang.webservice.DemoTest - =========================对象================================
14:44:41.151 [main] INFO com.kang.webservice.DemoTest - 当前值:User(id=4, userId=tom, userName=汤姆)
14:44:41.159 [main] INFO com.kang.webservice.DemoTest - 最终值:User(id=4, userId=我被不发份子绑票了, userName=汤姆)
14:44:41.159 [main] INFO com.kang.webservice.DemoTest - =========================数组================================
14:44:41.208 [main] INFO com.kang.webservice.DemoTest - 当前值:[1,2,3,4]
14:44:41.209 [main] INFO com.kang.webservice.DemoTest - 最终值:[1,3,4,5]
14:44:41.209 [main] INFO com.kang.webservice.DemoTest - =========================Map================================
14:44:41.244 [main] INFO com.kang.webservice.DemoTest - 当前值:{"user":{"id":2,"userId":"66","userName":"测试01"}}
14:44:41.244 [main] INFO com.kang.webservice.DemoTest - 最终值:{"user":{"id":2,"userId":"没有赎金惨遭撕票","userName":"测试01"}}
总结
可以看到方法中的引用数据类型的值被修改了,因为传引用后指向的是同一个地址,修改的实际上也就是这个地址上的值,另外要注意一点的是如果对象被重新创建或赋值为null,即new会重新指向其他对象,不影响其原对象的值。
public final class String
implements java.io.Serializable, Comparable, CharSequence,
Constable, ConstantDesc {
public final class Integer extends Number
implements Comparable, Constable, ConstantDesc {
/**
* String,Integer,Long
*/
@Test
public void test4(){
log.info("=========================String================================");
String value = "我是真的美猴王";
log.info("当前值:{}",value);
changeString(value);
log.info("最终值:{}",value);
log.info("=========================Integer================================");
Integer i = 10;
log.info("当前值:{}",i);
changeInteger(i);
log.info("最终值:{}",i);
}
private void changeInteger(Integer i) {
i = 10000*i;
}
private void changeString(String value) {
value = "你看我几分像从前";
}
结果
14:55:08.815 [main] INFO com.kang.webservice.DemoTest - =========================String================================
14:55:08.817 [main] INFO com.kang.webservice.DemoTest - 当前值:我是真的美猴王
14:55:08.818 [main] INFO com.kang.webservice.DemoTest - 最终值:我是真的美猴王
14:55:08.819 [main] INFO com.kang.webservice.DemoTest - =========================Integer================================
14:55:08.819 [main] INFO com.kang.webservice.DemoTest - 当前值:10
14:55:08.819 [main] INFO com.kang.webservice.DemoTest - 最终值:10
总结
String、Integer、Double等immutable类型因为类的变量设为final属性,无法被修改,只能重新赋值或生成对象。当Integer作为方法参数传递时,对其赋值会导致原有的引用被指向了方法内的栈地址,失去原有的的地址指向,所以对赋值后的Integer做任何操作都不会影响原有值。
基本类型(byte,short,int,long,double,float,char,boolean)为传值,传的是副本所以不会影响原有的值
对象类型(Object,数组,容器)为传引用,会影响原来的值
String、Integer、Double等immutable类型因为类的变量设为final属性,无法被修改,只能重新赋值或生成对象。当Integer作为方法参数传递时,对其赋值会导致原有的引用被指向了方法内的栈地址,失去原有的的地址指向,所以对赋值后的Integer做任何操作都不会影响原有值。