引用传递进阶分析
引用传递是Java的精髓,也是初学者最难学到地方。以下用三道题进行分析。
范例:第一道
class Demo{
private int num=10;
public Demo(int num){
this.num=num;
}
public void setNum(int num){
this.num=num;
}
public int getNum(){
return this.num;
}
}
public class Hello {
public static void main(String args[]){
Demo demo=new Demo(100);
fun(demo);
System.out.println(demo.getNum());//30
}
public static void fun(Demo temp){
temp.setNum(30);
}
}
范例:第二道
public class Hello {
public static void main(String args[]){
String str="hello";
fun(str);
System.out.println(str);//hello
}
public static void fun(String temp){
temp="world";
}
}
字符串一旦声明就不可改变,字符串对象内容的改变依靠的是引用的改变实现的。
范例:第三道
class Demo{
private String msg="Hello";
public Demo(String msg){
this.msg=msg;
}
public void setMsg(String msg){
this.msg=msg;
}
public String getMsg(){
return msg;
}
}
public class Hello {
public static void main(String args[]){
Demo demo=new Demo("world");
fun(demo);
System.out.println(demo.getMsg());//MLDN
}
public static void fun(Demo temp){
temp.setMsg("MLDN");
}
}
两种分析模式:
第一种:把String当成基本数据类型那样分析
这样的描述严格来讲并不标准,毕竟String属于引用数据类型,所以应该按照严格的方式进行描述。
第二种:
总结
引用传递一定要耐心使用内存分析,String这种类型的数据需要特殊处理。
引用传递实例分析
描述这样一个程序:一个人有一辆车。
进行数据库设计时,要描述以上内容,数据表该如何设计:
如果现在需要进行类的设计,也需要两个类:Person、Car,就可以发现两者的关联:
- 表名称=类名称;
- 表的字段=类属性;
- 表的一行记录=一个实例化对象;
- 表的多行记录=对象数组;
- 表的外键关系=引用设置。
所以Java类的设计要与数据表一一对应。
范例:定义类
class Person{
private int pid;
private String name;
//car为空,表示这个人没有车
private Car car;//一个人有一辆车
public Person(int pid,String name){
this.pid=pid;
this.name=name;
}
public String getPersonInfo(){
return "编号:"+this.pid+",姓名:"+this.name;
}
public void setCar(Car car){
this.car=car;
}
public Car getCar(){
return this.car;
}
}
class Car{
private String Cname;
//如果人有车了,必须同时修改人和车的关系
private Person person;//一辆车属于一个人
public Car(String cname){
this.Cname=cname;
}
public void setPerson(Person person){
this.person=person;
}
public Person getPerson(){
return this.person;
}
public String getCarInfo(){
return "汽车名称:"+this.Cname;
}
}
此时程序使用了自定义类型,Person、Car都是类。随后进行代码测试。测试分两步:设置内容,取出内容。
public class Hello {
public static void main(String args[]){
//第一步:根据已有的结构设置内容
Person per = new Person(1,"小胖");
Car car=new Car("小皮卡");
per.setCar(car);//人有车了
car.setPerson(per);//车属于一个人类
//第二步:根据关系取出数据
System.out.println(per.getPersonInfo());
System.out.println(per.getCar().getCarInfo());//代码链
System.out.println(car.getPerson().getPersonInfo());
System.out.println(car.getCarInfo());//代码链
}
}
代码链要看每个方法的返回值是什么,如果是一个类的对象,则可以继续调用该类的方法。
也可以针对此代码进一步扩展。每个人有孩子,每个孩子也有车。实际上每个人的孩子一定是人,并且跟人具备同样的属性,那么就可以在Person设计一个孩子的属性。
class Person{
private int pid;
private String name;
private Person child;//孩子
//car为空,表示这个人没有车
private Car car;//一个人有一辆车
public Person(int pid,String name){
this.pid=pid;
this.name=name;
}
public void setChild(Person child){
this.child=child;
}
public Person getChild(){
return this.child;
}
public String getPersonInfo(){
return "编号:"+this.pid+",姓名:"+this.name;
}
public void setCar(Car car){
this.car=car;
}
public Car getCar(){
return this.car;
}
}
class Car{
private String Cname;
//如果人有车了,必须同时修改人和车的关系
private Person person;//一辆车属于一个人
public Car(String cname){
this.Cname=cname;
}
public void setPerson(Person person){
this.person=person;
}
public Person getPerson(){
return this.person;
}
public String getCarInfo(){
return "汽车名称:"+this.Cname;
}
}
public class Hello {
public static void main(String args[]){
//第一步:根据已有的结构设置内容
Person per = new Person(1,"小胖");
Person chd = new Person(2,"小壮壮");
Car c=new Car("碰碰车");
Car car=new Car("小皮卡");
per.setCar(car);//人有车了
car.setPerson(per);//车属于一个人类
per.setChild(chd);//一个人有一个孩子
chd.setCar(c);//孩子有辆车
//第二步:根据关系取出数据
//找到一个人的孩子的信息
System.out.println(per.getChild().getPersonInfo());
//通过父亲的车找到父亲的信息,找到父亲的孩子的车的信息
System.out.println(car.getPerson().getChild().getCar().getCarInfo());
}
}
引用的关系可以描述出不同类之间的引用关系。
在现实生活中,这样的设计实际上不麻烦。
总结
- 不要把程序只当程序;
- 引用传递除了进行数据的分析之外,还需要掌握类与类的联系使用;
- 代码链的使用必须熟练。