美文网首页程序员
Java 变量参数传入方法,修改后是否影响外面的值

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

作者: 尉昌达 | 来源:发表于2020-07-10 22:59 被阅读0次

今天在公司做的一个订购成功后发送给用户的邮件时,见到了之前别人留下来的一个问题。类似于下面这样的代码:

public class Test {
    public static void test(List<Person> persons) {
        Map<String,Person> map = new HashMap<>();

        //把name相同的person合并,age相加
        for (Person person : persons) {
            if(map.containsKey(person.getName())) {
                Person person1 = map.get(person.getName());
                person1.setAge(person.getAge() + person1.getAge());
            } else {
                map.put(person.getName(),person);
            }
        }
        Collection<Person> values = map.values();
        //这个persons指向新new的一个对象
        persons = new ArrayList<>(values);
        System.out.println(persons.toString());//-->[Person{name='s1', age='8'}]
    }

    public static void main(String[] args){
        ArrayList<Person> persons = new ArrayList<>();
        persons.add(new Person("s1",5));
        persons.add(new Person("s1",3));

        test(persons);

        System.out.println(persons);//-->[Person{name='s1', age='8'}, Person{name='s1', age='3'}]
    }

}
  • main函数中外部有一个persons对象,传入test函数中,test函数中又把persons指向了一个新的对象,for循环中直接操作了persons中的对象。看下代码中的输出,persons的打印方法内外不一样。

下面的例子清晰点:

public class Test2 {
 
    public static void setValue(String str){
        str = "ss";
    }
    public static void setValue(Man str){
        str = new Man("test");
    }
 
    public static class Man{
        private String name;
 
        public String getName() {
            return name;
        }
 
        public void setName(String name) {
            this.name = name;
        }
 
        public Man(String name) {
            this.name = name;
        }
 
        @Override
        public String toString() {
            return "Man{" +
                    "name='" + name + '\'' +
                    '}';
        }
    }
 
    public static void main(String[] args) {
 
        String str = "s";
        setValue(str);
 
        System.out.println(str);
 
 
        Man man = null;
        setValue(man);
        System.out.println(man);
 
    }
}

上面代码输出:

s
null

原因是方法在执行的时候有栈帧的概念,入栈的时候只是压栈,方法参数是传入参数的副本。

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

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

比如

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();
        setValue(str);
 
        System.out.println(str.toString()); //输出空字符串
 
 
        setValue2(str);
        System.out.println(str.toString()); //输出sss
 
    }

关于String,本质是final类型char数组,不可修改,只能赋值,在做参数传入方法修改时,其实是新建对象,必须返回重新对外面的变量赋值才会对外面的String引用生效。

原文链接:https://blog.csdn.net/fenglllle/article/details/81389286

相关文章

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

    今天在公司做的一个订购成功后发送给用户的邮件时,见到了之前别人留下来的一个问题。类似于下面这样的代码: main函...

  • 参数传递

      当函数的参数类型是基本类型时,调用函数时会将参数拷贝一份传入函数,在函数中改变变量的值不会对函数外造成影响。当...

  • 为什么说 Java 中只有值传递?

    值传递和引用传递概念 在方法调用时,在方法内部对参数修改,如果影响到参数的原始值,那么就是引用传递;如果修改后,参...

  • Java基础-ThreadLocal

    ThreadLocal三个主要方法 set方法,用于设置当前线程本地变量的值,传入的参数为要设置的值。比如 thr...

  • Javascript中数组和字符串的常用方法

    Javascript中数组与字符串常用方法 数组常用方法 学习思路:这个方法干啥用?是否要传入参数?是否有返回值?...

  • 2018-10-12代码测试接口

    接口 java 导入 : import 类:方法-变量 方法:声明--权限 无返回值类型 方法名(参数列表){方法...

  • 宏、const

    const:1、将一些常见的变量变成只读变量。 2、方法参数,传入一个地址,不允许在方法内部修改外界值。 宏: c...

  • 按值传递与按引用传递

    按值传递与按引用传递 按值传递:传入的方法参数是原始数据类型,那么在方法内对该参数做任何处理都不会影响外部参数按引...

  • Dart语言基础(四)之函数方法(Function)

    方法定义 方法包含:返回类型、方法名、传入参数、方法体、返回值 返回类型 方法名(参数1,参数2...) { ...

  • ts 泛型 获取输入类型的对象

    一种方法使返回值的类型与传入参数的类型是相同的,这里,我们使用了 类型变量,它是一种特殊的变量,只用于表示类型而不是值。

网友评论

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

    本文链接:https://www.haomeiwen.com/subject/zppvcktx.html