搜索
首页Javajava教程一起聊聊JAVA中字符串和数组做参数传递

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于java字符串和数组做参数传递情况的相关问题,下面就来看一下为什么说java只有值传递,希望对大家有帮助。

一起聊聊JAVA中字符串和数组做参数传递

推荐学习:《java学习教程

首先明确的一点就是在java中只有值传递!只有值传递!理论依据来自《think in java》。接下来就是具体说明为何java只有值传递。
因为java中有基本类型和引用类型两种数据类型,再加上String这个特殊的类型,所以主要从三个方面就行解释。

1. 基本数据类型

先看代码

public class Demo01 {
    
    public void change(int a) {
        System.out.println("副本a 的初始值" + a);
        a = 20;
        System.out.println("副本a 的新值值" + a);
    }

    public static void main(String[] args) {
        int a = 10;
        Demo01 d = new Demo01();
        d.change(a);
        System.out.println("change方法执行后的值" + a);
    }
}

分析:

        在java中基本数据类型遵循值传递,所以对象d在调用change()方法时,只是将原数据a的副本传给方法中的参数,第一时间原本和副本a的值都是10,在执行到a=20后,副本a的值变成了20。

所以运行结果为:

原理参考下图

2. 引用数据类型

先看代码

public class Demo02 {

    char[] ch = {'a', 'b', 'c'};

    public void change(char ch[]) {
        System.out.println("方法中ch[0]的初始值:" + ch[0]);
        ch[0] = 'g';
        System.out.println("方法中ch[0]执行后的新值:" + ch[0]);
    }

    public static void main(String[] args) {
        Demo02 d = new Demo02();
        System.out.println("对象d中数组的初始值是:"+d.ch);
        d.change(d.ch);
        System.out.println("对象d中数组的最终值是:"+d.ch);
    }
}

分析:

        在引用类型作为参数进行传递时,也属于值传递,此时传递的是地址值副本,但是这两个地址指向同一个地方。在副本地址没有进行更改指向时,对副本地址指向的数据进行操作会影响到原始数据的值。方法中ch[] 数组和原始ch[]数组指向同一个数据,所以初始阶段ch[0]都指向’a’;接着对副本中的ch[0]进行新的赋值变为‘g’。
所以运行结果为:

 原理参考下图

3. 字符串的参数传递

先看代码

public class Demo03 {
    public void change(String str2) {
        System.out.println("方法中str2初始值" + str2);
        System.out.println("方法中str2初始hashcode值" + str2.hashCode());
        str2 = "bbb";
        System.out.println("方法中str2赋值后:" + str2);
        System.out.println("方法中str2赋值后hashcode值:" + str2.hashCode());
    }

    public static void main(String[] args) {
        String str1 = new String("aaa");
        System.out.println("原始字符串str1的hashcode值:" + str1.hashCode());
        Demo03 d = new Demo03();
        d.change(str1);
        System.out.println("方法调用后str1的值" + str1);
    }
}

分析:

        字符串是一个特殊的数据类型,它的底层是一个final 型的char[]数组,属于无法更改,所以字符串在作为参数传递时,可以当做一个特殊的数组进行操作,同样的它也是将复制一份原本的对象引用给了副本,此时副本对象的引用和原本对象的引用都指向原始字符串的位置,也就是str2在刚开始初始化时它指向的地址和原对象str1指向的位置一致,即str2的初始hashcode值和原对象str1的hashcode值一样,str2经过str2=“bbb”操作后,由于字符串的不可变性,此时str2会指向一个新的对象引用,即此时str2指向“bbb”的位置。str2的hashcode值会变化,但是原本str1它的对象引用没有发生改变,并且“aaa”也未发生改变,所以str1仍然指向”aaa”。运行结果如下:

接下来看一个更具体的字符串例子:

public class Demo04 {

    public static void main(String[] args) {
        StringBuffer s = new StringBuffer("hello");
        StringBuffer s2 = new StringBuffer("hi");
        test(s, s2);
        System.out.println("方法調用后s的值:" + s);
        System.out.println("方法調用后s2的值:" + s2);
    }

    static void test(StringBuffer s3, StringBuffer s4) {
        System.out.println("方法初始化時s3的值" + s3);
        System.out.println("方法初始化時s4的值" + s4);
        s4 = s3;
        s3 = new StringBuffer("new");
        System.out.println("第一步变化后s3的值" + s3);
        System.out.println("第一步变化后s4的值" + s4);
        s3.append("boy");
        s4.append("gril");
        System.out.println("第二步变化后s3的值" + s3);
        System.out.println("第二步变化后s4的值" + s4);

    }
}

这次先看结果:

然后进行分析:

在未执行方法之前,字符串s1和s2指向的位置分别是“hello”和“hi”,这个毋容置疑,

(1)接着进入方法内部,方法中参数s3和s4初始化时和上面例子相同,此时它们和s1s2指向同一个位置,或者说s1s2将对象引用副本给了s3s4,此时s3s4的值为“hello”和“hi”

(2)接着执行s4=s3,这个操作就是将s3的对象引用给了s4,此时s4为“hello”;s3=new StringBuffer(”new”);这个操作要注意,此时相当于给了s3一个新的对象引用,s3指向一个字符串为“new”的位置,所以此时s3=“new”,s4=“hello”

(3)然后s3.append(“boy”);s4.append(“gril”);在StringBuffer中的append方法要注意,它的操作不会为s3s4指向一个新的对象引用,是在原来的基础上进行操作,因此操作完之后s3=“newboy”,s4=“hellogril”

(4)此时方法调用完,回头捋一下s3s4在此过程中的对s1s2的影响。
——- A . 首先是s3和s1一样刚开始指向“hello”,接着给s3创建一个新的对象引用“new”,此时s3和s1再无半毛钱关系,s3进行append(boy)后,s3=“newboy”;
——– B . s4刚开始和s2都指向“hi”,接着s3将自己初始值(也就是s1的副本)给了s4,此时s4指向“hello”(这会s4和s1有了关系),s4执行append(grill)操作,因为它和s1指向相同位置,所以它们的共同指向的对象会变化,s4=s1=“hellogrill”。
——- C .然后就清楚了,s2指向的对象“hi”并未变化,s1指向的“hello”在append(“grill”)操作下变成了“hellogril”。

4. 总结

  •  当使用基本数据类型作为方法的形参时,在方法体中对形参的修改不会影响到实参的数值

  • 当使用引用数据类型作为方法的形参时,若在方法体中修改形参指向的数据内容,会对实参变量的数值产生影响,因为形参变量和实参变量共享同一块堆区;

  • 当使用引用数据类型作为方法的形参时,若在方法体中改变了形参变量的指向,此时不会对实参变量的数值产生影响,因此形参变量和实参变量分别指向不同的堆区;最后一个例子就是最形象的解释。

  • 关于字符串做参数,也是看它的参数变量指向是否发生了变化,因为String的底层为final类型的char[]原因,当你在String s = “aaa”还是String s = new String(“aaa”)时,都会为s创建一个新的对象引用。但是调用了append()方法时,是不会指向新的对象,会在原来的指向的对象上发生改变,与它共享的对象引用也会发生变化。

  • 最后重复的是java中没有引用传递,只有值传递,引用类型属于特殊值传递(是将它的地址副本给了参数,但是它与基本数据类型不同,如果地址指向的对象发生了变化,因为共享原因,原始对象也会改变)。

推荐学习:《java教程

以上是一起聊聊JAVA中字符串和数组做参数传递的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文转载于:CSDN。如有侵权,请联系admin@php.cn删除
带你搞懂Java结构化数据处理开源库SPL带你搞懂Java结构化数据处理开源库SPLMay 24, 2022 pm 01:34 PM

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于结构化数据处理开源库SPL的相关问题,下面就一起来看一下java下理想的结构化数据处理类库,希望对大家有帮助。

Java集合框架之PriorityQueue优先级队列Java集合框架之PriorityQueue优先级队列Jun 09, 2022 am 11:47 AM

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于PriorityQueue优先级队列的相关知识,Java集合框架中提供了PriorityQueue和PriorityBlockingQueue两种类型的优先级队列,PriorityQueue是线程不安全的,PriorityBlockingQueue是线程安全的,下面一起来看一下,希望对大家有帮助。

完全掌握Java锁(图文解析)完全掌握Java锁(图文解析)Jun 14, 2022 am 11:47 AM

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于java锁的相关问题,包括了独占锁、悲观锁、乐观锁、共享锁等等内容,下面一起来看一下,希望对大家有帮助。

一起聊聊Java多线程之线程安全问题一起聊聊Java多线程之线程安全问题Apr 21, 2022 pm 06:17 PM

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于多线程的相关问题,包括了线程安装、线程加锁与线程不安全的原因、线程安全的标准类等等内容,希望对大家有帮助。

Java基础归纳之枚举Java基础归纳之枚举May 26, 2022 am 11:50 AM

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于枚举的相关问题,包括了枚举的基本操作、集合类对枚举的支持等等内容,下面一起来看一下,希望对大家有帮助。

详细解析Java的this和super关键字详细解析Java的this和super关键字Apr 30, 2022 am 09:00 AM

本篇文章给大家带来了关于Java的相关知识,其中主要介绍了关于关键字中this和super的相关问题,以及他们的一些区别,下面一起来看一下,希望对大家有帮助。

Java数据结构之AVL树详解Java数据结构之AVL树详解Jun 01, 2022 am 11:39 AM

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于平衡二叉树(AVL树)的相关知识,AVL树本质上是带了平衡功能的二叉查找树,下面一起来看一下,希望对大家有帮助。

java中封装是什么java中封装是什么May 16, 2019 pm 06:08 PM

封装是一种信息隐藏技术,是指一种将抽象性函式接口的实现细节部分包装、隐藏起来的方法;封装可以被认为是一个保护屏障,防止指定类的代码和数据被外部类定义的代码随机访问。封装可以通过关键字private,protected和public实现。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
3 周前By尊渡假赌尊渡假赌尊渡假赌

热工具

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

将Eclipse与SAP NetWeaver应用服务器集成。

mPDF

mPDF

mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

安全考试浏览器

安全考试浏览器

Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。