Java变量参数传入方法,修改后是否影响外面的值

https://blog.csdn.net/fenglllle/article/details/81389286
原因是方法在执行的时候有栈帧的概念,入栈的时候只是压栈方法参数是传入参数的副本。

JVM高级特性

此时区分数据类型:基本类型和引用类型

基本类型:值存放在局部变量表中,无论如何修改只会修改当前栈帧的值,方法执行结束对方法外不会做任何改变;此时需要改变外层的变量,必须返回主动赋值。

引用数据类型:指针存放在局部变量表中,调用方法的时候,副本引用压栈,赋值仅改变副本的引用。但是如果直接改变副本引用的值,修改了引用地址的对象,此时方法以外的引用此地址对象当然被修改。(两个引用,同一个地址,任何修改行为2个引用同时生效)

    @RequestMapping(value = "/ttt/{id}")
    public String ttt(@PathVariable("id") Long id)
    {
        //查询商品基本信息
        GoodInfoBean goodInfoBean = new GoodInfoBean();
        System.out.println("111============="+goodInfoBean.hashCode());
        GoodInfoBean gg = test(goodInfoBean, id);
        System.out.println("222============="+goodInfoBean.hashCode());
        System.out.println("333=============gg="+gg.hashCode());
        System.out.println("ggg============="+goodInfoBean);
        return "ddd";
    }
    public GoodInfoBean test(GoodInfoBean gg,Long id){
        System.out.println("2-111============="+gg.hashCode());
        gg.setId(222L);//修改后,GoodInfoBean的hashCode就会变动了!!!
        gg = goodInfoJPA.findOne(id);
        gg.setId(333L);
        System.out.println("2-222============="+gg.hashCode());
        System.out.println("2-333============="+gg);
        return gg;
    }  
111=============1244802162
2-111=============1244802162
Hibernate: 
   select
       goodinfobe0_.tg_id as tg_id1_0_0_,
       goodinfobe0_.tg_order as tg_order2_0_0_,
       goodinfobe0_.tg_price as tg_price3_0_0_,
       goodinfobe0_.tg_title as tg_title4_0_0_,
       goodinfobe0_.tg_type_id as tg_type_5_0_0_ 
   from
       good_infos goodinfobe0_ 
   where
       goodinfobe0_.tg_id=?
2-222=============472670822
2-333=============GoodInfoBean(id=333, title=芹菜, price=12.4, order=1, typeId=1)
222=============-881157515
333=============gg=472670822
ggg=============GoodInfoBean(id=222, title=null, price=0.0, order=0, typeId=null)

关于String,本质是final类型char数组,不可修改,只能赋值,在做参数传入方法修改时,其实是新建对象,必须返回重新对外面的变量赋值才会对外面的String引用生效。
看String源码的任意一个方法即可明白
引用类型会引起浅拷贝和深拷贝现象。
测试代码:

public static void setValue(StringBuilder str){
    str = new StringBuilder("sss");
}
public static void setValue2(StringBuilder str){
    str.append("sss");
}
public static void main(String[] args) {

    StringBuilder str = new StringBuilder();
    System.out.println("1==="+str.hashCode());
    setValue(str);
    System.out.println("2==="+str.hashCode());

    System.out.println(str.toString()); //输出空字符串

    setValue2(str);
    System.out.println("3==="+str.hashCode());
    System.out.println(str.toString()); //输出sss

    String a="111";
    System.out.println(a.hashCode());
    a="222";
    System.out.println(a.hashCode());
}

1===1607521710 2===1607521710

3===1607521710 sss 48657 49650 string源码: /** * Returns a string resulting from replacing all occurrences of * {@code oldChar} in this string with {@code newChar}. *

* If the character {@code oldChar} does not occur in the * character sequence represented by this {@code String} object, * then a reference to this {@code String} object is returned. * Otherwise, a {@code String} object is returned that * represents a character sequence identical to the character sequence * represented by this {@code String} object, except that every * occurrence of {@code oldChar} is replaced by an occurrence * of {@code newChar}. *

* Examples: *

* "mesquite in your cellar".replace('e', 'o')
*         returns "mosquito in your collar"
* "the war of baronets".replace('r', 'y')
*         returns "the way of bayonets"
* "sparring with a purple porpoise".replace('p', 't')
*         returns "starring with a turtle tortoise"
* "JonL".replace('q', 'x') returns "JonL" (no change)
* 
* * @param oldChar the old character. * @param newChar the new character. * @return a string derived from this string by replacing every * occurrence of {@code oldChar} with {@code newChar}. / public String replace(char oldChar, char newChar) { if (oldChar != newChar) { int len = value.length; int i = -1; char[] val = value; / avoid getfield opcode */

        while (++i < len) {
            if (val[i] == oldChar) {
                break;
            }
        }
        if (i < len) {
            char buf[] = new char[len];
            for (int j = 0; j < i; j++) {
                buf[j] = val[j];
            }
            while (i < len) {
                char c = val[i];
                buf[i] = (c == oldChar) ? newChar : c;
                i++;
            }
            //String的value 是final char[],一旦创建不能改变
            return new String(buf, true);
        }
    }
    return this;
}
end