【JavaSE基础】深入了解Java的传值和传引用

简介: 【JavaSE基础】深入了解Java的传值和传引用

⭐️小题目⭐️


public static void main(String[] args) {
        int a=10;
        test(a);
        System.out.println(a);
    }
    public static void test(int a){
        a=20;
    }

           如果你能知道马上知道a输出的值仍然是10,说明你了解初步的传值引用,不过后面我讲细讲Java的传值引用。如果你觉得a是20的话,那就请更加认真观看后文,Java的传值引用,是非常基础且重要的东西,因为Java并没有C的指针,无法进行传址引用


🌳 1.什么是传值引用?


        首先,大家肯定对形参和实参两个名词不陌生,肯定从开始接触编程就挺过,老师常说方法的参数列表就是形参。但是我们需要传入的参数肯定都遍布在计算机的各个位置,JVM编译的时候不可能到各个地方去寻找参数列表中的参数。对于每个需要进入到参数列表的参数不可能自己移动,于是乎每个参数都克隆出和自己一模一样的数据,去到一个地方排好队被JVM识别。这些原本的参数就是实参,被克隆出的数据就是形参,形参排队的地方就是栈内存区。


       这时候有同学就疑问了,你不是介绍什么是传值引用吗?怎么变成介绍形参和实参了?且听下框解释


  🔑  这种实参复制到栈中去成为形参的过程就是我们的传值引用的过程。    


      小题目中主方法中的a收到了test方法给出的邀请函,但由于实在a无法离开自己所在的岗位,于是乎克隆了一份和自己属性一样的数据去参加了test方法举办的宴会,结果最后被克隆的a被改变成了20。然后我们需要打印出a的值,被克隆的a被改变了,难道会改变原来a的值吗?当然不会,所以我们打印a出来还是10。


🌳2.Java如何实现传引用?


🍋1.数组的值传递


       学习Java的同学大部分肯定都先接触过C语言,既然学习C语言那就一定绕不开指针,指针是什么呢?大家肯定都知道是地址,所以C语言是有按址传递的。难道Java没有传址的情况吗?当然有,看下列代码


public static void main(String[] args) {
       int[] arr={1,2,3,4};
       test(arr);
        System.out.println(arr[0]);//10
    }
    public static void test(int[] arr){
        arr[0]=10;
    }

      有的人看到输出答案为10,肯定觉得我上文说错了,你明明说传值引用不会改变原本的值,怎么数组arr的第一个元素1变成了10了?首先要明白,这里确实是传值引用,但是这个值是我们学过的基本数据类型吗?arr它是一个数组!有的人可能到现在还没明白问题出在哪,那我就再原文再加一行输出代码


public static void main(String[] args) {
       int[] arr={1,2,3,4};
       test(arr);
        System.out.println(arr[0]);//10
        System.out.println(arr);//[I@14ae5a5
    }
    public static void test(int[] arr){
        arr[0]=10;
    }

       数组名代表的是一个地址,它并不是某个具体的元素,当我们传入数组名时,其实也是传值引用,只不过这个值是一个地址而已。自身的值我可以复制相同的,难道地址可以复制相同的吗?所以你在test方法中做的改动,直接就改变了原本的arr数组。所以这就是关于数组的传值引用


🍋2.对象的值传递


      传参除了传入基本数据类型和数组外,还可以传什么?很多人肯定会想到对象,没错,对于传入一个对象它又是什么情况呢?我们通过代码一端代码来看


public static void main(String[] args) {
        Student student = new Student("王宝强", 1);
        test(student);
        System.out.println(student);
    }
    public static void test(Student student){
        student.name="宋喆";
        student.id=2;
    }
}
class Student{
    String name;
    int id;
    public Student(String name, int id) {
        this.name = name;
        this.id = id;
    }
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", id=" + id +
                '}';
    }


image.png


     我们发现实例对象student的两个属性name和id都被修改了,不仅同上面数组的例子产生思考,难道对象也是一个地址,于是我们去掉重写的toString方法,在调用test方法前后输出student对象。


public static void main(String[] args) {
            Student student = new Student("王宝强", 1);
            System.out.println(student);//Student@14ae5a5
            test(student);
        }
        public static void test(Student student){
            System.out.println(student);//Student@14ae5a5
            student.name="宋喆";
            student.id=2;
        }

         如我们所料,果然student是一个地址,在方法外部和内部而且都是相同的地址,说明我们在test方法内部修改的对象正是外面的实例对象。传入实例对象原来就是传入该对象的地址。


🌳3.如何判断是传值还是传引用?


       其实很多人都把这种传数组和对象的情况叫做传引用,它并不是真正意义上的传址。


   🌺 那我们是不是一定要搞清楚传值还是传引用的问题吗?


       是必要但不是非要,首先我们要明白Java的思想,在Java中任何东西都是以类来生存,有的人马上反驳,不对啊,基本数据类型int,byte,char等等的基本数据类型不是啊。但很多人却不不知道与其对应的还有Integer,Byte,Character这三个类。这更加完美的为Java以类而生的思想提供佐证。有的人马上会觉得我跑题了,但这却是我们分辨传值还是传引用的基础。


   🎨 判断传值和传引用的问题贯穿我们的学习和生活中,解决它的能力更多地在于我们平时对Java的积累和理解


public static void main(String[] args) {
       int a=10;
       int b=200;
       exch(a,b);
        System.out.println(a);//10
        System.out.println(b);//100
    }
    public static void exch(int a,int b) {
        int temp=a;
        a=b;
        b=temp;
    }

       我现在给上这段代码,很多人马上就能知道为什么a和b的值交换失败,可即使再牛的Java的大佬,在他初学阶段也难免写出过这样的代码。能一眼看出错误,正是源于我们平时的积累,多思考而不是去钻牛角尖,才是正确的学习方法。


相关文章
|
6月前
|
存储 Java 测试技术
滚雪球学Java(18):解密JavaSE中的堆栈:你真的了解Java内存吗?
【4月更文挑战第7天】🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
64 1
滚雪球学Java(18):解密JavaSE中的堆栈:你真的了解Java内存吗?
|
6月前
|
Java
滚雪球学Java(17):探索循环控制:JavaSE中的break与continue秘技
【4月更文挑战第6天】🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
66 1
滚雪球学Java(17):探索循环控制:JavaSE中的break与continue秘技
|
1月前
|
存储 缓存 Java
java基础:IO流 理论与代码示例(详解、idea设置统一utf-8编码问题)
这篇文章详细介绍了Java中的IO流,包括字符与字节的概念、编码格式、File类的使用、IO流的分类和原理,以及通过代码示例展示了各种流的应用,如节点流、处理流、缓存流、转换流、对象流和随机访问文件流。同时,还探讨了IDEA中设置项目编码格式的方法,以及如何处理序列化和反序列化问题。
70 1
java基础:IO流 理论与代码示例(详解、idea设置统一utf-8编码问题)
|
5月前
|
Java
【Java基础】输入输出流(IO流)
Java基础、输入输出流、IO流、流的概念、输入输出流的类层次结构图、使用 InputStream 和 OutputStream流类、使用 Reader 和 Writer 流类
172 2
|
2月前
|
安全 Java API
【Java面试题汇总】Java基础篇——String+集合+泛型+IO+异常+反射(2023版)
String常量池、String、StringBuffer、Stringbuilder有什么区别、List与Set的区别、ArrayList和LinkedList的区别、HashMap底层原理、ConcurrentHashMap、HashMap和Hashtable的区别、泛型擦除、ABA问题、IO多路复用、BIO、NIO、O、异常处理机制、反射
【Java面试题汇总】Java基础篇——String+集合+泛型+IO+异常+反射(2023版)
|
5月前
|
安全 Java
|
5月前
|
搜索推荐 算法 Java
【Java基础】 几种简单的算法排序
几种简单的JAVA算法排序
54 4
|
6月前
|
存储 安全 Java
滚雪球学Java(19):JavaSE中的内存管理:你所不知道的秘密
【4月更文挑战第8天】🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
68 4
滚雪球学Java(19):JavaSE中的内存管理:你所不知道的秘密
|
5月前
|
存储 缓存 Java
Java基础17-读懂Java IO流和常见面试题(二)
Java基础17-读懂Java IO流和常见面试题(二)
42 0
|
5月前
|
存储 Java Unix
Java基础17-读懂Java IO流和常见面试题(一)
Java基础16-读懂Java IO流和常见面试题(一)
76 0
下一篇
无影云桌面