引用传递
1 引用传递进阶分析
引用传递是java的整体核心,下面用三个程序进行引用传递分析。
1.1 第一道引用传递
代码
class Message {
private int 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();
msg.setNum(100);
System.out.println(msg.getNum());
fun(msg); // Message temp = msg
System.out.println(msg.getNum());
}
public static void fun(Message temp){ // 引用传递
temp.setNum(30);
}
}
- 输出结果
100
30
内存分析如下:
1.2 第二道引用传递
代码
public class TestDemo {
public static void main(String args[]){
String str = "hello";
System.out.println(str);
fun(str);
System.out.println(str);
}
public static void fun(String temp){ // 引用传递
temp = "world";
}
}
- 输出结果
hello
hello
结果还是hello,字符串常量一旦声明则不可改变,字符串对象的内容改变依靠的是地址的引用关系变更。
内存分析如下:
1.3 第三道引用传递
代码
class Message {
private String note;
public void setNote(String note){
this.note = note;
}
public String getNote(){
return this.note;
}
}
public class TestDemo {
public static void main(String args[]){
Message msg = new Message();
msg.setNote("hello");
System.out.println(msg.getNote());
fun(msg); // Message temp = msg
System.out.println(msg.getNote());
}
public static void fun(Message temp){ // 引用传递
temp.setNote("world");
}
}
- 输出结果
hello
world
对以上代码进行分析,有一个前提:先把String类的使用当做一个基本数据类型来操作。
内存分析如下:
String按照引用类型分析:
2 引用传递实际应用
因为有了引用传递,才可以更好的表现出现实世界的抽象。
例如,现在要求描述一种关系:一个人有一辆汽车或没有汽车。有两个实体类:人(Member)、车(Car)。
范例:得到如下设计
代码
class Member{
private String name;
private int age;
// 如果car == null,表示这个人没有车
private Car car; // 一个人只能有一辆车
public Member(String name,int age){
this.name = name;
this.age = age;
}
public void setCar(Car car) {
this.car = car;
}
public Car getCar() {
return this.car;
}
public String getMemberInfo(){
return "【Member】 name = " + this.name + ", age = " + this.age;
}
}
class Car{
private String name;
private double price;
private Member member;
public void setMember(Member member) {
this.member = member;
}
public Member getMember() {
return this.member;
}
public Car(String name, double price){
this.name = name;
this.price = price;
}
public String getCarInfo(){
return "【Car】 name = " + this.name + ", price = " + this.price;
}
}
public class TestDemo {
public static void main(String args[]) {
// 第一步:根据关系设置相应的数据
// 1.分别创建各自对象的实例
Member mem = new Member("Jack",30);
Car car = new Car("Ferrari",5000000.00);
// 2.设置对象间引用关系
mem.setCar(car);
car.setMember(mem);
// 第二步:根据关系取出数据
// 3.通过人找车
System.out.println(mem.getCar().getCarInfo());
// 4.通过车找人
System.out.println(car.getMember().getMemberInfo());
}
}
- 输出结果
【Car】 name = Ferrari, price = 5000000.0
【Member】 name = Jack, age = 30
进一步设计:Jack会有后代,后代还会有车。
- 建立一个孩子类,若果有孙子,继续建孙子类,明显不可能。
- 在Member类中直接建立一个新的属性,描述的是孩子,孩子的类型就是Member。
范例:得到如下设计
代码
class Member{
private String name;
private int age;
private Member child;
public void setChild(Member child) {
this.child = child;
}
public Member getChild() {
return this.child;
}
// 如果car == null,表示这个人没有车
private Car car; // 一个人只能有一辆车
public Member(String name,int age){
this.name = name;
this.age = age;
}
public void setCar(Car car) {
this.car = car;
}
public Car getCar() {
return this.car;
}
public String getMemberInfo(){
return "【Member】 name = " + this.name + ", age = " + this.age;
}
}
class Car{
private String name;
private double price;
private Member member;
public void setMember(Member member) {
this.member = member;
}
public Member getMember() {
return this.member;
}
public Car(String name, double price){
this.name = name;
this.price = price;
}
public String getCarInfo(){
return "【Car】 name = " + this.name + ", price = " + this.price;
}
}
public class TestDemo {
public static void main(String args[]) {
// 第一步:根据关系设置相应的数据
// 1.分别创建各自对象的实例
Member mem = new Member("Jack",30); // 你
Car car = new Car("Ferrari",5000000.00); // 你的车
Member chd = new Member("Tom",6); // 你的孩子
Car ccar = new Car("Ford",30.00); // 你孩子的车
// 2.设置对象间引用关系
mem.setCar(car);
mem.setChild(chd); // 你的孩子
chd.setCar(ccar); // 孩子的车
car.setMember(mem);
// 第二步:根据关系取出数据
// 3.通过人找车
System.out.println(mem.getCar().getCarInfo());
// 4.通过车找人
System.out.println(car.getMember().getMemberInfo());
// 5.通过人找孩子
System.out.println(mem.getChild().getMemberInfo());
// 6.通过人找孩子的车,代码链
System.out.println(mem.getChild().getCar().getCarInfo());
}
}
- 输出结果
【Car】 name = Ferrari, price = 5000000.0
【Member】 name = Jack, age = 30
【Member】 name = Tom, age = 6
【Car】 name = Ford, price = 30.0
程序扩展:一台电脑由显示器、主机、键盘、硬盘、鼠标、主板、CPU、内存组成。
伪代码
class 电脑{
private 主机 对象;
private 显示器 [] 对象;
private 鼠标 [] 对象;
private 键盘 [] 对象;
}
class 显示器{ }
class 主机{
private CPU [] 对象;
}
class 鼠标{ }
class 主板{
private CPU [] 对象;
private 内存 [] 对象;
private 硬盘 [] 对象;
}
class CPU{ }
class 内存{ }
class 硬盘{ }
只有将这些细小的类合并到一起才能狗描述出一个完整的概念,这些细小的组成都可以进行替代替换。这样的设计属于合成设计模式。实际开发中,所使用到的类都要求开发者自己定义,这些里面都使用了引用传递。