深刻理解Java中形參与实參,引用与对象的关系
声明:本博客为原创博客,未经同意。不得转载!
原文链接为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中形參与实參,引用与对象的关系的更多相关文章
- 深刻理解Java中final的作用(一):从final的作用剖析String被设计成不可变类的深层原因
声明:本博客为原创博客,未经同意,不得转载!小伙伴们假设是在别的地方看到的话,建议还是来csdn上看吧(原文链接为http://blog.csdn.net/bettarwang/article/det ...
- 深刻理解Java中的String、StringBuffer和StringBuilder的差别
声明:本博客为原创博客,未经同意.不得转载!小伙伴们假设是在别的地方看到的话,建议还是来csdn上看吧(链接为http://blog.csdn.net/bettarwang/article/detai ...
- JDK学习---深入理解java中的HashMap、HashSet底层实现
本文参考资料: 1.<大话数据结构> 2.http://www.cnblogs.com/dassmeta/p/5338955.html 3.http://www.cnblogs.com/d ...
- 理解Java中的弱引用(Weak Reference)
本篇文章尝试从What.Why.How这三个角度来探索Java中的弱引用,理解Java中弱引用的定义.基本使用场景和使用方法.由于个人水平有限,叙述中难免存在不准确或是不清晰的地方,希望大家可以指出, ...
- [译]线程生命周期-理解Java中的线程状态
线程生命周期-理解Java中的线程状态 在多线程编程环境下,理解线程生命周期和线程状态非常重要. 在上一篇教程中,我们已经学习了如何创建java线程:实现Runnable接口或者成为Thread的子类 ...
- 深入理解Java中的不可变对象
深入理解Java中的不可变对象 不可变对象想必大部分朋友都不陌生,大家在平时写代码的过程中100%会使用到不可变对象,比如最常见的String对象.包装器对象等,那么到底为何Java语言要这么设计,真 ...
- 深入理解Java中的IO
深入理解Java中的IO 引言: 对程序语言的设计者来说,创建一个好的输入/输出(I/O)系统是一项艰难的任务 < Thinking in Java > 本文的目录视图如下: ...
- [转]深刻理解Python中的元类(metaclass)以及元类实现单例模式
使用元类 深刻理解Python中的元类(metaclass)以及元类实现单例模式 在看一些框架源代码的过程中碰到很多元类的实例,看起来很吃力很晦涩:在看python cookbook中关于元类创建单例 ...
- 理解Java中的ThreadLocal
提到ThreadLocal,有些Android或者Java程序员可能有所陌生,可能会提出种种问题,它是做什么的,是不是和线程有关,怎么使用呢?等等问题,本文将总结一下我对ThreadLocal的理解和 ...
随机推荐
- Maven实战读书笔记(四):Maven生命周期与插件
Maven的生命周期是对所有构建过程的抽象和统一.包含了项目的清理.初始化.编译.测试.打包.集成测试.验证.部署和站点生成等几乎所有构建步骤. Maven的生命周期是抽象的,其实际行为是由插件来完成 ...
- sql语句执行顺序与性能优化(1)
一.首先我们看一下mysql的sql语句的书写顺序 . select--distinct--from--on--where--group by--having--聚合函数cube.rollup--or ...
- c++_分巧克力(75分)
#include <iostream> using namespace std; int n,k; ],w[]; bool fen(int bian){ ; ;i<n;i++){ c ...
- 条款30:透彻了解inline的里里外外(understand the ins and outs of inlining)
NOTE: 1.将大多数inline限制在小型 被频繁调用的函数身上.这可使日后的调试过程和二进制升级(binary upgradability)更容易,也可使潜在的代码膨胀问题最小化, 使程序的速度 ...
- Saving James Bond - Hard Version
07-图5 Saving James Bond - Hard Version(30 分) This time let us consider the situation in the movie &q ...
- [第一波模拟\day3\T3]{益智游戏}(game.cpp)
[问题描述] 小P和小R在玩一款益智游戏.游戏在一个正权有向图上进行. 小P控制的角色要从A点走最短路到B点,小R控制的角色要从C点走最短路到D点. 一个玩家每回合可以有两种选择,移动到一个相邻节点或 ...
- centos挂载本地镜像作为yum源
1.安装Centos后默认的Yum源如下 ll /etc/yum.repos.d/ [root@localhost ~]# ll /etc/yum.repos.d/ total 32 -rw-r- ...
- github私有库购买信息
github私有库购买信息 一年84美元. 换算成人民币是:532元. 话说其他开发者都买了么?
- Python补充--Python内置函数清单
Python内置函数 Python内置(built-in)函数随着python解释器的运行而创建.在Python的程序中,你可以随时调用这些函数,不需要定义.最常见的内置函数是: print(&quo ...
- Codeforces Round #211 (Div. 2)-D. Renting Bikes,二分!感谢队友出思路!
D. Renting Bikes 读懂题后一开始和队友都以为是贪心.可是贪心又怎么贪呢..我们无法确定到底能买多少车但肯定是最便宜的前x辆.除了公共预算每个人的钱只能自己用,也无法确定每个人买哪一辆车 ...