zoukankan      html  css  js  c++  java
  • Java 的参数传递

    一、传值和传址(引用)

    Java 的参数传递分为传递基本数据类型(传值)和传递引用数据类型(传址)

    public class Demo {
    
        public void fun(Test test, int i) {
            test.name = "test2";
            i = 2;
            System.out.println(i);
        }
    
        public static void main(String[] args) {
            Demo demo = new Demo();
            Test test = new Test();
            int i = 1;
            demo.fun(test, i);
            System.out.print(test.name + " and " + i);
        }
    }
    
    class Test {
        String name = "test";
    }
    
    2
    test2 and 1
    

    对于基本数据类型,当我们修改传递的值,原来的值不会改变,所以传递的是值的拷贝。值的拷贝在一块儿新的内存中。

    对于引用数据类型,当我们通过传递的引用变量修改对象的属性,原引用指向的对象也将改变,所以没有将对象的数据拷贝传递,传递的是指向对象的引用变量,即对象的地址。当然,引用变量是值传递,引用变量的拷贝在一块儿新的内存中。

    正常来说,传值更符合正常思路。我把值传给你,你使用它,不会影响我的值。

    因为传址的特点,可以将大数据存放到对象中,传递对象引用,减少参数(局部变量表)的大小以提高栈帧的空间利用率。

    二、String 的参数传递

    public class Demo {
    
        String str = new String("hello");
        char[] ch = {'a', 'b', 'c'};
    
        public void fun(String str, char[] ch) {
            str = "world";
            ch[0] = 'd';
        }
    
        public static void main(String[] args) {
            Demo demo = new Demo();
            demo.fun(demo.str, demo.ch);
            System.out.print(demo.str + " and ");
            System.out.print(demo.ch);
        }
    }
    
    hello and dbc
    
    1. 局部变量 str 和全局变量 str 这 2 个名称相同变量,但内存位置不同的值都是 0x1001(假设)
    2. 对象 test 调用 fun 方法,将实参 test.str(全局变量 str 存放对象 "hello" 的内存地址)和 test.ch(全局变量 ch 存放字符数组对象的内存地址),传给 fun 方法的形参 str 引用和 ch 引用。
    3. 局部变量 str 存放对象 "hello" 的内存地址。"world" 匿名对象, str = "world"; 等价于 str = new String("world") ,相当于将在堆中重新分配一个内存空间存放 "world",局部变量 str 指向 "world"。局部变量 str 的生命周期和方法相同,只是名称和全局变量 str 相同

    以上两步操作在 JVM 中如下图所示,内存地址为假设。

    image

    1. char ch[] 与 char[] ch 等价。语句 ch[0] = 'd'; 将替换字符数组对象中下标为 0 的字符,即改变了对象的内容。test.str 没有改变,还是 "hello",test.ch 从 "abc" 改为 "dbc"。

    IDEA 调试图如下:

    image

    2.1、理解引用存放地址

    Book a == new Book();// 对象 1
    Book b == new Book();// 对象 2
    b = a;
    

    问:那个对象会被回收? 答:对象 2,因为将引用 a 中存放对象 1 的地址赋值给了引用 b,所以引用 b 将 “指向” 对象 1,对象 2 将被回收。

    三、总结

    可以将地址视为值,所以传值和传址都可以视为传值。

    四、延伸阅读

  • 相关阅读:
    C语言中条件表达式求最大值和最小值
    面向对象编程:Java的简单数据类型
    JAVA学习经验谈
    JAVA的入门基础一些精典
    面向对象编程:Java复杂数据类型用法
    面向对象编程:Java的简单数据类型
    面向对象编程:Java collection更有效管理elements
    从C++到Java 理解面向对象是关键所在
    JAVA学习经验谈
    JAVA的入门基础一些精典
  • 原文地址:https://www.cnblogs.com/deppwang/p/13894002.html
Copyright © 2011-2022 走看看