传递的是值的副本。方法中对副本的修改,不会影响到调用方,也就是不会影响原来的值;
传递的是引用的副本,共用一个内存,会影响到调用方。此时,形参和实参指向同一个内存地址。
但是对引用副本本身(对象地址)的修改,如设置为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做任何操作都不会影响原有值。