Java String 值传递 VS 引用传递

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java String 值传递 VS 引用传递相关的知识,希望对你有一定的参考价值。

在Java代码中,如果方法参数中有String类型,那么这个参数是值传递还是方法传递呢?

基本类型容易理解,对象类型也容易理解,可偏偏String这个对象类型让人有些疑惑。别着急,看完你就清晰了。

其实,我们大可不必纠结于文字游戏,在Java中宣称只有值传递,而在C++程序员来看要区分为值传递和引用/指针传递,实质上是一致的。

 

1. 对于基本类型,如int、char,大家都能理解,属于值传递,一个方法中对于基本类型的修改,不会反馈到方法调用者。

    public static void main(String[] args)
    {
        int a = 111;
        change(a);
        System.out.println("in method main, a = " + a);
    }
    
    private static void change(int a)
    {
        a = 789;
        System.out.println("in method change, a = " + a);
    }

输出:

in method change, a = 789
in method main, a = 111

 

2. 对于对象类型,值传递,传递的是对象的地址,而不是对象的内容。所以,在方法内只要不修改对象的地址,那么对象内容的修改就会反馈到方法调用者,因为方法内外见到的是同一个地址。

    public static void main(String[] args)
    {
        Student studentA = new Student();
        studentA.age = 18;
        change(studentA);
        System.out.println("in method main, age = " + studentA.age);
    }
    
    private static void change(Student student)
    {
        student.age = 46;
        System.out.println("in method change, age = " + student.age);
    }
    
    private static class Student
    {
        private int age;
        
        /**
         * 取得age 
         * @return 返回 age
         */
        public int getAge()
        {
            return age;
        }
        
        /**
         * 设置age
         * @param age 要设置的age
         */
        public void setAge(int age)
        {
            this.age = age;
        }
    }

输出:

in method change, age = 46
in method main, age = 46

 

3. 接着第2条说,如果参数是对象类型,但是在方法内,参数重新指向了别的对象,即参数的地址发生了变化。那么对这个参数的修改将不会反馈到方法调用者,因为方法内外见到的不是同一个地址。

    public static void main(String[] args)
    {
        Student studentA = new Student();
        studentA.age = 18;
        change(studentA);
        System.out.println("in method main, age = " + studentA.age);
    }
    
    private static void change(Student student)
    {
        student = new Student();
        student.age = 46;
        System.out.println("in method change, age = " + student.age);
    }

输出:

in method change, age = 46
in method main, age = 18

 

4. String类型。为什么String类型作为参数传递,修改String不能反馈到方法调用者呢?因为在Java中有个常量池,每个字符串都对应常量池中的一个对象,也就是说,如果对String对象重新赋值,就相当于将String指向了另一个对象,地址发生了改变。下面两端代码是等效的。

代码一:

    public static void main(String[] args)
    {
        String str = "111";
        change(str);
        System.out.println("in method main, str = " + str);
    }
    
    private static void change(String str)
    {
        str = "222";
        System.out.println("in method change, str = " + str);
    }

代码二:

    public static void main(String[] args)
    {
        String str = new String("111");
        change(str);
        System.out.println("in method main, str = " + str);
    }
    
    private static void change(String str)
    {
        str = new String("222");
        System.out.println("in method change, str = " + str);
    }

输出都一样:

in method change, str = 222
in method main, str = 111

以上是关于Java String 值传递 VS 引用传递的主要内容,如果未能解决你的问题,请参考以下文章

java 的String和StringBuffer引用传递问题

String 不变性以及Java 值传递和引用传递

java是值传递还是引用传递?

JAVA 参数的 值传递和引用传递(特殊的String 和 StringBuild)

JAVA 参数的 值传递和引用传递(特殊的String 和 StringBuild)

java:按值传递或按引用传递[重复]