1.基本概念:引用传递是整个Java的精髓所在,其核心意义是:同一块堆内存空间可以被不同的栈内存所指向,不同栈内存可以对同意堆内存进行内容的修改
例.第一道引用传递范例
class Message{
private int num = 10;
/**
* 本类没有提供无参构造方法,而是提供有参构造,可以接收num属性的内容
* @param num 接收num属性的内容
*/
public Message(int num){
this.num = num;
}
public void setNum(int num){
this.num = num;
}
public int getnum(){
return this.num;
}
}
public class TestDemo{
public static void main(String args[]){
Message msg = new Message(30); //实例化Message类对象同时传递num属性内容
fun(msg); //引用传递
System.out.println(msg.getnum());
}
/**
* 修改Message类中的num属性内容
* @param temp Message类的引用
* @param temp
*/
public static void fun(Message temp){
temp.setNum(100); //修改num属性内容
}
}
100
本例首先在Message类中定义一个num属性,之后利用Message类的构造方法进行num属性的赋值操作,最后在主方法中调用fun()方法,在fun()方法的参数上接收了Message类对象的引用,以便可以修改num属性的内容
例.第二道引用范例
public class TestDemo{
public static void main(String args[]){
String msg = "Hello";
fun(msg); //引用传递
System.out.println(msg);
}
public static void fun(String temp){ //接收字符串引用
temp = "World"; //改变字符串引用
}
}
Hello
本程序首先定义一个String类的对象,内容为"Hello",之后将此对象的引用传递给fun()方法中的temp,即两个String类对象都指向一个堆内存空间,但是由于String对象内容的变化是通过引用的改变实现的,所以在fun()方法中所作的任何修改都不会影响到原本的msg对象内容,最终结果保持不变
注:可以先不把String作为引用数据类型,而是作为基本数据类型(例如int等基本数据类型,在引用时同样不会改变初始值)
例.第三道引用传递
public class TestDemo{
public static void main(String args[]){
Message msg = new Message("Hello");
fun(msg); //引用传递
System.out.println(msg.getInfo());
}
public static void fun(Message temp){ //接收Message类引用
temp.setInfo("world"); //修改info属性内容
}
}
class Message{
private String info = "此方法无用";
public Message(String info){
this.info = info;
}
public void setInfo(String info){
this.info = info;
}
public String getInfo(){
return this.info;
}
}
world
本例中通过结合Message类的方法,使temp和msg具备同一块堆内存空间的引用,从而达到修改String内容的目的
2.引用传递实际应用
理论上显示生活中的一切都可以进行合理的抽象,下面设计这样一种类:假如每个人都有一辆汽车或都没有汽车,显然,人是一个类,而车也是一个类人应该包含一个车的属性,反过来车也包含一个人的属性
例.代码实现(无参构造、setter、getter略,同时程序定义的是两个简单Java类)
class Member{
private int mid; //人员编号
private String name; //人员姓名
private Car car; //表示属于人的车,如果没有车则内容为null
public Member(int mid,String name){
this.mid = mid;
this.name = name;
}
public void setCar(Car car){
this.car = car;
}
public Car getCar(){
return this.car;
}
public String getInfo(){
return "人员编号:" + this.mid + ";姓名:" + this.name;
}
}
class Car{
private Member member; //车属于一个人,如果没有所属者,则为null
private String pname; //车的名字
public Car(String pname){
this.pname = pname;
}
public void setMember(Member member){
this.member = member;
}
public Member getMember(){
return this.member;
}
public String getInfo(){
return "车的名字:" + this.pname;
}
}
本程序类完成后,需要对程序进行测试,而程序的测试要求分为以下两步:
- 第一步:根据定义的结构关系设置数据
- 第二部:根据定义的结构关系取出数据
例.代码测试
public class TestDemo{
public static void main(String args[]){
//一、根据既定结构设置数据
Member m = new Member(1,"王涵");
Car c = new Car("九手思域100");
m.setCar(c); //一个人有一辆车
c.setMember(m); //一辆车属于一个人
//二、根据既定结构取出关系
System.out.println(m.getCar().getInfo()); //通过人找到车的信息
System.out.println(c.getMember().getInfo()); //通过车找到人的信息
}
}
车的名字:九手思域100
人员编号:1;姓名:王涵
本程序首先实例化了Member和Car各自的对象,然后分别利用各自类中的setter方法设置了对象间的引用关系
对于以上一对一的关系是相对比较容易操作的,可以进行进一步设计:每个人都有自己的孩子,孩子还可能有车:
- 方法一:如果有后代就需要设计一个类,按照这个思路,对下一代又要设计一个类,而且这些类的结构是完全一样的,这样不利于程序的简洁化
- 方法二:一个人的孩子仍然定义为一个人,和人的本质没有区别,可以在Member类里面设计一个属性表示孩子,其类型还是Member
例.修改Member类定义
class Member{
private int mid; //人员编号
private String name; //人员姓名
private Car car; //表示属于人的车,如果没有车则内容为null
private Member child; //表示人的孩子,如果没有,则为null
public Member(int mid,String name){
this.mid = mid;
this.name = name;
}
public void setCar(Car car){
this.car = car;
}
public Car getCar(){
return this.car;
}
public void setClild(Member child){
this.child = child;
}
public Member getChild(){
return child;
}
public String getInfo(){
return "人员编号:" + this.mid + ";姓名:" + this.name;
}
}
class Car{
private Member member; //车属于一个人,如果没有所属者,则为null
private String pname; //车的名字
public Car(String pname){
this.pname = pname;
}
public void setMember(Member member){
this.member = member;
}
public Member getMember(){
return this.member;
}
public String getInfo(){
return "车的名字:" + this.pname;
}
}
public class TestDemo{
public static void main(String args[]){
//一、根据既定结构设置数据
Member m = new Member(1,"王涵");
Member chd = new Member(2,"金世轶");
Car c = new Car("九手思域100");
Car cc = new Car("法拉利M9");
m.setCar(c); //一个人有一辆车
c.setMember(m); //一辆车属于一个人
chd.setCar(cc);
cc.setMember(chd);
m.setClild(chd); //一个人有一个孩子
//二、根据既定结构取出关系
System.out.println(m.getCar().getInfo()); //通过人找到车的信息
System.out.println(c.getMember().getInfo()); //通过车找到人的信息
System.out.println(m.getChild().getInfo());
System.out.println(m.getChild().getCar().getInfo());
}
}
车的名字:九手思域100
人员编号:1;姓名:王涵
人员编号:2;姓名:金世轶
车的名字:法拉利M9
本程序在Member类中增加了一个表示孩子的属性:child,其类型为Member类型,如果一个人有孩子则为其设置一个实例化对象,如果没有则设置为null