Java中传值和传址

Wesley13
• 阅读 610

本文用一下代码说明:

Java代码 Java中传值和传址

简单字符串String:

  1. package luojing;

  2. public class StringDemo

  3. {

  4. public static void main(String[]args)

  5. {

  6. String str=new String("hello");

  7. //调用函数改变str的值

  8. change(str);

  9. System.out.println(str);

  10. }

  11. public static void change(String str1)

  12. {

  13. str1+="luojing";

  14. }

  15. }

程序执行结果:  hello

StringBuffer:

  1. public class StringDemo

  2. {

  3. public static void main(String[]args)

  4. {

  5. StringBuffer str=new StringBuffer("hello");

  6. //调用函数改变str的值

  7. change(str);

  8. System.out.println(str);

  9. }

  10. public static void change(StringBuffer str1)

  11. {

  12. str1.append("luojing");

  13. }

  14. }

程序运行结果 :hello luojing        这个时候str的内容就改变了。

将上面的StringBuffer换成我们自己定义的对象:

  1. public class test

  2. {

  3. public static void main(String[] args)

  4. {

  5. Demo demo=new Demo("hello");

  6. //调用函数该变demo.name的值

  7. change(demo);

  8. System.out.println(demo.getName());

  9. }

  10. public static void change(Demo d)

  11. {

  12. d.setName("luojing");

  13. }

  14. }

  15. class Demo

  16. {

  17. private String name;

  18. public Demo(String s)

  19. {

  20. name=s;

  21. }

  22. public String getName()

  23. {

  24. return name;

  25. }

  26. public void setName(String str)

  27. {

  28. name=str;

  29. }

  30. }

程序运行结果: luojing 和我们使用StringBuffer对象是效果相同。

我们再对change()方法做一些修改:

  1. package luojing;

  2. public class test

  3. {

  4. public static void main(String[] args)

  5. {

  6. Demo demo=new Demo("hello");

  7. //调用函数该变demo.name的值

  8. change(demo);

  9. System.out.println(demo.getName());

  10. }

  11. public static void change(Demo d)

  12. {

  13. Demo d1=new Demo("hello java");

  14. d=d1;

  15. }

  16. }

  17. class Demo

  18. {

  19. private String name;

  20. public Demo(String s)

  21. {

  22. name=s;

  23. }

  24. public String getName()

  25. {

  26. return name;

  27. }

  28. public void setName(String str)

  29. {

  30. name=str;

  31. }

  32. }

运行结果: hello
可以看到,虽然我们在change()方法中对d进行了改变,而实际的对象demo并没有改变。

  1. class Foo {

  2. private int x;

  3. public Foo(int x) {

  4. this.x = x;

  5. }

  6. public void setX(int x) {

  7. this.x = x;

  8. }

  9. public int getX() {

  10. return x;

  11. }

  12. }

  13. public class Submit {

  14. static Foo fooBar(Foo foo) {

  15. foo = new Foo(100);

  16. return foo;

  17. }

  18. public static void main(String[] args) {

  19. Foo foo = new Foo(300);

  20. System.out.print(foo.getX() + "-");

  21. Foo fooFoo = fooBar(foo);

  22. System.out.print(foo.getX() + "-");

  23. System.out.print(fooFoo.getX() + "-");

  24. foo = fooBar(fooFoo);

  25. System.out.print(foo.getX() + "-");

  26. System.out.print(fooFoo.getX());

  27. }

  28. }

What is the output of the program shown in the exhibit?
A. 300-100-100-100-100
B. 300-300-100-100-100
C. 300-300-300-100-100
D. 300-300-300-300-100

Answer: B

涉及知识点:
1.Java中的参数传递有传值和传址两种;
2.基本类型和String型作为参数时,为传值方式,只把值传入方法,不管在方法中怎么处理这个参数,原值不变;
3.其他引用类型作为参数时,为传址方式,将指向内存中的地址传入方法,方法中此内存地址中的值发生变化时,原值也会改变;
4.例外:
(1)如果引用类型的对象通过传址方式将其指向内存中的地址传入方法后,方法中使用new关键字重新给参数赋值时,会在内存中重新开辟空间,参数指向新的内存空间,此时参数和原对象指向的就不是同一个地址了,参数值的变化不会改变原值;
(2)String型是引用类型,但是String型作为参数,是传值方式,可以通过以下两种方式来理解:
<1>String本质上是基本类型的char[],基本类型作为参数时,为传值方式;
<2> 字符串在内存中是存储在堆中的一个常量,String对象指向内存中这个常量的地址,通过传址方式将地址传入方法后,方法中如果通过字符串给参数赋值,则会重新在堆中创建一个字符串常量,并指向这个地址,原值依然指向原来的字符串常量地址,参数值的变化不会改变原值,如果通过new关键字给参数赋值,参见 (1)中的解释。

解析:
1.“Foo foo = new Foo(300);”,此时foo.getX()的值为300;
2.“Foo fooFoo = fooBar(foo);”,因为Foo是引用类型,main方法中的foo通过传址的方式将其指向的地址传给fooBar方法中的foo,此时两个foo指向同一个地址,foo.getX()的值都为300;通过“new Foo(100)”给fooBar方法中的foo赋值后,该foo重新指向了一个新的地址,foo.getX()的值为新地址中的值100,而main方法中的foo仍然指向原来的地址,foo.getX()的值没有改变,仍为 300;fooBar将foo的值返回给fooFoo,因此fooFoo.getX()的值为100;
3.“foo = fooBar(fooFoo);”,同2中的解释,foo.getX()的值变为100,fooFoo.getX()的值没有变化,仍为100;

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Stella981 Stella981
2年前
Python Excel Tutorial 指南
安装有几种不同的安装方法。下面是以xlrd为例的,其它二个库都是使用同样的步骤。从源码安装Linux系统:Python代码  !收藏代码(http://www.iteye.com/images/icon_star.png)(http://my.oschina.net/taisha/admin)1.$ tar 
Stella981 Stella981
2年前
HIVE 时间操作函数
日期函数UNIX时间戳转日期函数: from\_unixtime语法:   from\_unixtime(bigint unixtime\, string format\)返回值: string说明: 转化UNIX时间戳(从19700101 00:00:00 UTC到指定时间的秒数)到当前时区的时间格式举例:hive   selec
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
2年前
Docker 部署SpringBoot项目不香吗?
  公众号改版后文章乱序推荐,希望你可以点击上方“Java进阶架构师”,点击右上角,将我们设为★“星标”!这样才不会错过每日进阶架构文章呀。  !(http://dingyue.ws.126.net/2020/0920/b00fbfc7j00qgy5xy002kd200qo00hsg00it00cj.jpg)  2
Wesley13 Wesley13
2年前
unity将 -u4E00 这种 编码 转汉字 方法
 unity中直接使用 JsonMapper.ToJson(对象),取到的字符串,里面汉字可能是\\u4E00类似这种其实也不用转,服务器会通过类似fastjson发序列化的方式,将json转对象,获取对象的值就是中文但是有时服务器要求将传参中字符串中类似\\u4E00这种转汉字,就需要下面 publ
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
2个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这