深刻理解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的理解和 ...
随机推荐
- 12scrapy_redis
一.简介 1.redis redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zse ...
- python基础知识05-控制流程
控制流程 1.条件判断 python中的代码从上到下执行. if 条件: 缩进 语句1 elif 条件2: 缩进 语句2 (…或者写pass关键字.不写任何代码的时候,防止报错.) ... else: ...
- 第二天,学习if,变量,注释
zz_age = 31guss_age=int(input("input your answer:"))if guss_age == zz_age: print ("Yo ...
- UVa 1354 天平难题 (枚举二叉树)
题意: 分析: 其实刚看到这题的时候觉得很难, 以至于结束了第七章然后去做了一遍第六章树的部分.现在再做这题觉得思路并不是太难,因为总共就只有六个结点,那么只要枚举二叉树然后算出天平然后再从叶子往上推 ...
- netcat命令的使用
Linux netcat 命令实例: 1,端口扫描 端口扫描经常被系统管理员和黑客用来发现在一些机器上开放的端口,帮助他们识别系统中的漏洞. $nc -z -v -n 172.31.100.7 21- ...
- HDU3183A Magic Lamp,和NYOJ最大的数一样
A Magic Lamp Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tot ...
- SPOJ VJudge QTREE - Query on a tree
Query on a tree Time Limit: 851MS Memory Limit: 1572864KB 64bit IO Format: %lld & %llu Submi ...
- 《effective C++》:条款37——绝不重新定义继承而来的缺省参数值
引子: 阿里的一道题: #include <IOSTREAM> using namespace std; class A{ public: ) { cout<<"a~ ...
- php 之 日志系统seaslog安装
php 之 日志系统seaslog 特点: 1.高性能(使用C语言编写的). 2.无需配置. 3.功能完善.使用简单. 安装: 打开php的扩展官网:https://pecl.php.net/. 然后 ...
- Sudoku Killer--hdu1426(数独 跟上一题差不多 但是输入时问题)
http://acm.hdu.edu.cn/showproblem.php?pid=1426 注意输入问题就行 还是dfs #include<stdio.h> #include<st ...