iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >JAVA中字符串和数组做参数传递的示例分析
  • 364
分享到

JAVA中字符串和数组做参数传递的示例分析

2023-06-29 17:06:38 364人浏览 泡泡鱼
摘要

这篇文章主要介绍JAVA中字符串和数组做参数传递的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!首先明确的一点就是在java中只有值传递!只有值传递!理论依据来自《think in 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。

所以运行结果为:

JAVA中字符串和数组做参数传递的示例分析

原理参考下图

JAVA中字符串和数组做参数传递的示例分析

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’。
所以运行结果为:

JAVA中字符串和数组做参数传递的示例分析

原理参考下图

JAVA中字符串和数组做参数传递的示例分析

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”。运行结果如下:

JAVA中字符串和数组做参数传递的示例分析

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

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);    }}

这次先看结果:
JAVA中字符串和数组做参数传递的示例分析

然后进行分析:

在未执行方法之前,字符串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中字符串和数组做参数传递的示例分析”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注编程网精选频道!

--结束END--

本文标题: JAVA中字符串和数组做参数传递的示例分析

本文链接: https://www.lsjlt.com/news/325828.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 如何在 Golang 中替换正则表达式匹配的文本?
    在 go 中,可使用 regexp.replaceall 函数替换符合正则表达式的文本,该函数需要三个参数:待替换字符串、匹配模式和替换文本。例如,将字符串中 "fox" 替换为 "do...
    99+
    2024-05-14
    golang 正则表达式
  • 如何在 Golang 中测试随机数生成器的准确性?
    在 go 中测试随机数生成器准确性的步骤包括:生成大量随机数并计算每个范围内的出现次数,以确保均匀分布。针对指定均值和标准差计算每个范围内的出现次数,以确保正态分布。 如何在 Gola...
    99+
    2024-05-14
    golang 随机数
  • 面向对象设计原则在C++中的体现
    c++++ 体现了 oop 原则,包括:封装:使用类将数据和方法封装在对象中。继承:允许派生类从基类继承数据和行为。多态:允许对象的行为根据其类型而改变,通过虚函数实现。 面向对象设计...
    99+
    2024-05-14
    c++ 面向对象
  • c语言怎么区分小数和整数
    c 语言区分小数和整数的方法有:数据类型不同:小数类型(float、double)包含小数点,整数类型(int)不包含。printf() 函数中使用不同格式化字符串:小数用 %f,整数用...
    99+
    2024-05-14
    c语言
  • 设计模式在C++ 中的可复用性和可扩展性
    在 c++++ 中,设计模式通过提供经过验证的解决方案来提高可复用性和可扩展性。可复用性允许重复使用代码,例如 factory method 模式,它支持创建不同的产品而不影响具体类。可...
    99+
    2024-05-14
    c++ 设计模式 高可扩展性
  • C++语法中函数模板的灵活运用
    C++ 语法中函数模板的灵活运用 函数模板是 C++ 中的一项强大功能,允许您创建可用于不同数据类型的一组代码。这可以提高代码的可重用性,并使您能够编写更通用、更可维护的代码。 语法 ...
    99+
    2024-05-14
    c++语法 函数模板 c++
  • c语言怎么计算字符串长度和宽度
    在 c 语言中,计算字符串长度和宽度的函数分别为:strlen() 函数用于计算字符串长度,不包括终止符 '\0'。strwidth() 函数用于计算字符串在终端中的宽度,返回显示像素数...
    99+
    2024-05-14
    c语言
  • 如何用 Golang 正则匹配多个单词或字符串?
    golang 正则表达式使用管道符 | 来匹配多个单词或字符串,将各个选项作为逻辑 or 表达式分隔开来。例如:匹配 "fox" 或 "dog":fox|dog匹配 "quick"、"b...
    99+
    2024-05-14
    golang 正则 python
  • c语言怎么跳出多层循环
    在 c 语言中,可以使用嵌套的 break 语句跳出多层循环。对于每个要跳出的循环层,都需要一个单独的 break 语句。例如:使用一个 break 语句跳出内层循环再使用一个 brea...
    99+
    2024-05-14
    c语言
  • c语言怎么注释成中文
    c语言中文注释提供两种方式:行内注释(以"//"开头)和块注释(以"/"开头并以"/"结尾)。最佳实践包括:使用简明扼要的语言,在函数和类开头处添加块注释,在关键部分添加行内注释,保持注...
    99+
    2024-05-14
    c语言
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作