Java学习笔记----引用传递

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

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值