声明:本博客为原创博客,未经同意。不得转载!

原文链接为http://blog.csdn.net/bettarwang/article/details/30989755

我们都知道。在Java中,除了基本数据类型之外,其它的都是引用类型,当它们作为函数參数时,传递的也是引用。通过引用能够改变对象的值,非常多人便因此而忽略形參与实參,引用与对象的关系问题。废话不多说,先看以下一个样例:

import java.util.*;

public class Student
{
private String name;
private int age;
public Student(String name,int age)
{
this.name=name;
this.age=age;
}
public void printInfo()
{
System.out.println("Name:"+name+" age:"+age);
} public static void change(Student student)
{
Student stu=new Student("Lucy",26);
student=stu;
student.printInfo();
}
public static void main(String[]args)
{
Student s=new Student("Lily",25);
s.printInfo();
change(s);
s.printInfo();
}
}

执行结果例如以下:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvQmV0dGFyd2FuZw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

显然,形參改变了。可是实參没有被改变,这是为什么呢?

要分析这个问题。首先要分清Java中的引用与对象的关系,比方此处s是引用,它存储在栈中,而它指向的对象存储在堆中,所以当使用change函数时。实际上仅仅进行了下面操作:首先是将实參的值传给形參,即形參student也指向s所指向的对象;之后让student指向change函数中新建的对象。也就是说,在这个函数中,实參仅仅是在一開始起了一下作用,后面便再也没它的事儿了。我们添加一个输出操作就可以印证上面的结论。新代码例如以下:

import java.util.*;

public class Student
{
private String name;
private int age;
public Student(String name,int age)
{
this.name=name;
this.age=age;
}
public void printInfo()
{
System.out.println("Name:"+name+" age:"+age);
} public static void change(Student student)
{
//新增的输出操作
if(student!=null)
{
student.printInfo();
}
Student stu=new Student("Lucy",26);
student=stu;
student.printInfo();
}
public static void main(String[]args)
{
Student s=new Student("Lily",25);
s.printInfo();
change(s);
s.printInfo();
}
}

输出结果例如以下:



由输出结果可知确实是实參仅仅起了一次结合的作用,而在整个函数中实參s及其指向的对象都未被改变,所以显然change函数达不到对应的预期。实际上,要实现改变对象的目的,应该像以下这样写:

import java.util.*;

public class Student
{
private String name;
private int age;
public Student(String name,int age)
{
this.name=name;
this.age=age;
}
public void printInfo()
{
System.out.println("Name:"+name+" age:"+age);
}
public void setName(String name)
{
this.name=name;
}
public void setAge(int age)
{
this.age=age;
}
public static void change(Student student)
{
student.setName("Lucy");
student.setAge(26);
}
public static void main(String[]args)
{
Student s=new Student("Lily",25);
s.printInfo();
change(s);
s.printInfo();
}
}

输出结果例如以下:



显然,这个change函数达到了我们的预期,原因就在于它是真正地改变了对象的属性。

通过上面这个样例可知。尽管Java中传递的是引用,能够轻易地实现对对象的改变。可是仍然要注意形參与实參、引用与对象的关系。千万不要简单地以为传引用就一定能够实现对象的改变。否则可能犯下低级错误。

深刻理解Java中形參与实參,引用与对象的关系的更多相关文章

  1. 深刻理解Java中final的作用(一):从final的作用剖析String被设计成不可变类的深层原因

    声明:本博客为原创博客,未经同意,不得转载!小伙伴们假设是在别的地方看到的话,建议还是来csdn上看吧(原文链接为http://blog.csdn.net/bettarwang/article/det ...

  2. 深刻理解Java中的String、StringBuffer和StringBuilder的差别

    声明:本博客为原创博客,未经同意.不得转载!小伙伴们假设是在别的地方看到的话,建议还是来csdn上看吧(链接为http://blog.csdn.net/bettarwang/article/detai ...

  3. JDK学习---深入理解java中的HashMap、HashSet底层实现

    本文参考资料: 1.<大话数据结构> 2.http://www.cnblogs.com/dassmeta/p/5338955.html 3.http://www.cnblogs.com/d ...

  4. 理解Java中的弱引用(Weak Reference)

    本篇文章尝试从What.Why.How这三个角度来探索Java中的弱引用,理解Java中弱引用的定义.基本使用场景和使用方法.由于个人水平有限,叙述中难免存在不准确或是不清晰的地方,希望大家可以指出, ...

  5. [译]线程生命周期-理解Java中的线程状态

    线程生命周期-理解Java中的线程状态 在多线程编程环境下,理解线程生命周期和线程状态非常重要. 在上一篇教程中,我们已经学习了如何创建java线程:实现Runnable接口或者成为Thread的子类 ...

  6. 深入理解Java中的不可变对象

    深入理解Java中的不可变对象 不可变对象想必大部分朋友都不陌生,大家在平时写代码的过程中100%会使用到不可变对象,比如最常见的String对象.包装器对象等,那么到底为何Java语言要这么设计,真 ...

  7. 深入理解Java中的IO

    深入理解Java中的IO 引言:     对程序语言的设计者来说,创建一个好的输入/输出(I/O)系统是一项艰难的任务 < Thinking in Java >   本文的目录视图如下: ...

  8. [转]深刻理解Python中的元类(metaclass)以及元类实现单例模式

    使用元类 深刻理解Python中的元类(metaclass)以及元类实现单例模式 在看一些框架源代码的过程中碰到很多元类的实例,看起来很吃力很晦涩:在看python cookbook中关于元类创建单例 ...

  9. 理解Java中的ThreadLocal

    提到ThreadLocal,有些Android或者Java程序员可能有所陌生,可能会提出种种问题,它是做什么的,是不是和线程有关,怎么使用呢?等等问题,本文将总结一下我对ThreadLocal的理解和 ...

随机推荐

  1. 微信小程序:errcode=40029和invalid code, hints: [ req_id: VyLhYa0451hb31 ]

    问题: 后台用小程序返回的code请求微信服务器换取session_key和openid,返回错误状态码40029 解决问题 当前小程序绑定的appid和请求微信服务器所带的appid参数不一致导致的 ...

  2. 执行BarTender

    1.配置.btw模板 1.1.左侧创建“具名数据源” 1.2.条码属性,选择刚才的数据源 1.3.保存 2.配置.btin服务 2.1.点击 工具/Integration Builder” 2.2.创 ...

  3. 远程桌面mstsc关闭连接栏

    在进行mstsc远程桌面连接电脑或者虚拟机的时候,总是会出现一个连接栏.虽然点左边的图钉可以自动隐藏,但是每次鼠标滑到上面的时候,还是会冒出来,这个就有点烦心了. 查了下资料,解决了这个问题. 关闭步 ...

  4. 如何用 CSS 创作一个立体滑动 toggle 交互控件

    效果预览 在线演示 按下右侧的"点击预览"按钮在当前页面预览,点击链接全屏预览. https://codepen.io/zhang-ou/pen/zjoOgX 可交互视频教程 此视 ...

  5. Eclipse设置反编译插件

    有些项目我们想看看引入的包的源码的时候,因为打包好的.class文件的内容我们是看不懂的,但是又懒得去找源码文件的时候,就会用到反编译工具. 步骤: 1.安装反编译插件. 2.设置使用的反编译工具. ...

  6. python基础——6(字符编码,文件操作)

    今日内容: 1.字符编码: 人识别的语言与机器识别的语言转化的媒介 *****     2.字符与字节: 字符占多少字节,字符串转化 ***     3.文件操作: 操作硬盘中的一块区域:读写操作  ...

  7. MySql查询语句的使用实例

    一.设计表 1.设计表 查询语句之前先设计四张表:student.teacher.course.score student:sid(学号).sname(姓名).sage(年龄).ssex(性别) te ...

  8. HDU-1020-Encoding,题意不清,其实很水~~

    Encoding Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) http:// ...

  9. [Go]链表的相关知识

    切片有着占用内存少喝创建便捷等特点,但它本质上还是数组.切片的一大好处是可以通过窗口快速地定位并获取或者修改底层数组中的元素.不过当删除切片中的元素的时候就没那么简单了.元素复制一般是免不了的,就算只 ...

  10. poj 3155 二分+最小割求实型最小割(最大密集子图)

    /* 最大密集子图子图裸题 解法:设源点s和汇点t 根据胡波涛的<最小割模型在信息学中的应用> s-每个点,权值为原边权和m, 每个点-t,权值为m+2*g-degree[i], 原来的边 ...