美文网首页
引用传递

引用传递

作者: 落在牛背上的鸟 | 来源:发表于2018-03-08 22:05 被阅读20次

引用传递时整个Java的精髓所在,

核心意义:同一块堆内存空间可以被不同的栈内存所指向,不同栈内存可以对同一堆内存进行内容的修改。

范例一:

class Message {
    private int num = 10 ;
    public Message(int num) {
        this.num = num ;
    }
    public void setNum(int num) {
        this.num = num ;
    }
    public int getNum() {
        return this.num ;
    }
}

public class MessageDemo {
    public static void main(String[] args) {
        Message msg = new Message(30) ;
        fun(msg);
        System.out.println(msg.getNum());   //100
    }
    public static void fun(Message temp) {
        temp.setNum(100);
    }
}

内存分析图如下:


范例一

范例二

public class MessageDemo2 {
    public static void main(String[] args) {
        String msg = "Hello";
        fun(msg);
        System.out.println(msg);    //Hello
    }

    public static void fun(String temp) {
        temp = "World" ;
    }
}

以上代码需要注意的是:String类对象的内容一旦声明,则不可改变;对象内容的改变实际是引用地址的改变。


范例二

范例三

class Message3 {
    private String info = "Hello";
    public Message3(String info) {
        this.info = info;
    }
    public void setInfo(String info) {
        this.info = info;
    }
    public String getInfo() {
        return this.info;
    }
}

public class MessageDemo3 {
    public static void main(String[] args) {
        Message3 msg = new Message3("Hello");
        fun(msg);
        System.out.println(msg.getInfo());  //World
    }
    public static void fun(Message3 temp) {
        temp.setInfo("World");
    }
}
范例3简单内存图
上面的描述并不严格,因为在程序里面,info也是一个String类的对象,下面是较清楚的内存分析图
范例三严格内存图
结论:虽然String属于类,属于引用类型,但是由于其内容不可改变的特点,很多时候就直接把String当成基本数据类型那样使用,也就是说:每一个String变量只能够保存一个数据。

实际应用

例:每一个人都有一辆汽车或没有汽车;要求可以通过面向对象的方式来描述。
范例:代码设计如下

class Member {
    private int mid;
    private String name;
}

class Car {
    private String pname;
}

以上实现了两个独立的类,没有任何联系,但是可以通过引用传递来描述关系。

class Member {
    private int mid;
    private String name;
    //car 有实例化对象表示有车
    //car 为null 表示没有车
    private Car car;    //表示属于人的车
    public Member(int mid , String name) {
        this.mid = mid;
        this.name = name;
    }
    public String getInfo() {
        return "人员编号:" + this.mid + ", 姓名:" + this.name;
    }
}

class Car {
    private Member member;  //车属于一个人
    private String pname;
    public Car(String pname) {
        this.pname = pname;
    }
    public String getInfo() {
        return "车的名字: " + this.pname;
    }
}

当Member 或Car 类的对象产生之后,那么就应该为这两个对象设置彼此的关系。

class Member {
    private int mid;
    private String name;
    //car 有实例化对象表示有车
    //car 为null 表示没有车
    private Car car;    //表示属于人的车
    public Member(int mid , String name) {
        this.mid = mid;
        this.name = name;
    }
    public String getInfo() {
        return "人员编号:" + this.mid + ", 姓名:" + this.name;
    }
    public void setCar(Car car) {
        this.car = car;
    }
    public Car getCar() {
        return this.car;
    }
}

class Car {
    private Member member;  //车属于一个人
    private String pname;
    public Car(String pname) {
        this.pname = pname;
    }
    public String getInfo() {
        return "车的名字: " + this.pname;
    }
    public void setMember(Member member) {
        this.member = member;
    }
    public Member getMember() {
        return this.member;
    }
}

public class MemberCar{
    public static void main(String[] args){
        System.out.println("Hello World!");
    }
}

以上程序类完成之后,下面要对程序进行测试,但是程序的测试要求分两步:

  • 第一步:根据定义的结构关系设置数据;
  • 第二步:根据定义的结构关系取出数据。
public class MemberCar{
    public static void main(String[] args){
        //第一步:设置数据
        Member m = new Member(1 , "张三");    //独立对象
        Car c = new Car("BMW");     //独立对象
        m.setCar(c);    //一个人有一辆车
        c.setMember(m);     //一辆车属于一个人
        //第二步:取出关系
        //通过人找到车的信息
        System.out.println(m.getCar().getInfo());
        //通过车找到人的信息
        System.out.println(c.getMember().getInfo());
    }
}

还可以进一步设计,例如:每个人都有自己的孩子,孩子还可能有车,那么有两种设计方案:

  • 方案一:设计一个孩子类,如果有孙子,再定义一个孙子类,如果有曾孙,再定义个曾孙类。。。
  • 方案二:一个人的孩子一定还是一个人,与人的类没有本质的区别,所以可以在Member类里面设计一个属性,表示孩子,其类型就是Member
class Member {
    private int mid;
    private String name;
    private Member child;   //表示孩子
    //car 有实例化对象表示有车
    //car 为null 表示没有车
    private Car car;    //表示属于人的车
    public Member(int mid , String name) {
        this.mid = mid;
        this.name = name;
    }
    public String getInfo() {
        return "人员编号:" + this.mid + ", 姓名:" + this.name;
    }
    public void setCar(Car car) {
        this.car = car;
    }
    public Car getCar() {
        return this.car;
    }
    public void setChild(Member child) {
        this.child = child;
    }
    public Member getChild() {
        return this.child;
    }
}

class Car {
    private Member member;  //车属于一个人
    private String pname;
    public Car(String pname) {
        this.pname = pname;
    }
    public String getInfo() {
        return "车的名字: " + this.pname;
    }
    public void setMember(Member member) {
        this.member = member;
    }
    public Member getMember() {
        return this.member;
    }
}

public class MemberCar{
    public static void main(String[] args){
        //第一步:设置数据
        Member m = new Member(1 , "张三");        //独立对象
        Member chd = new Member(2, "王五");       //一个孩子对象
        Car c = new Car("BMW");     //独立对象
        Car cc = new Car("Ferrari");    //一辆车
        m.setCar(c);    //一个人有一辆车
        c.setMember(m);     //一辆车属于一个人
        chd.setCar(cc);     //孩子有一辆车
        cc.setMember(chd);  //一辆车属于孩子
        m.setChild(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());  //代码链
    }
}

相关文章

  • C++基础

    C++ 值传递、指针传递、引用传递详解C++中引用传递与指针传递区别 引用传递和指针传递的区别 引用的规则:(1)...

  • Day12-Java

    值传递和引用传递 值传递是值的拷贝, 引用传递是引用的拷贝 String 类型是引用类型, new String ...

  • var、let、const

    javascript对象是引用传递,基本类型是按值传递 ps:javascript里没有引用传递其实是传递引用? ...

  • python3 参数中的陷阱,可变对象和不可变对象

    介绍引用传递 python只允许使用引用传递, 不存在其他语言中的值传递。引用传递即引用内存地址, 无论是赋值还是...

  • Java中的参数传递

    为了便于理解,会将参数传递分为按值传递和按引用传递。按值传递是传递的值的拷贝,按引用传递传递的是引用的地址值,所以...

  • [译] Java 值传递 VS 引用传递

    Java是值传递还是引用传递一直都有争论,我们最终下个结论,Java是值传递而不是引用传递。如果Java是引用传递...

  • 引用传递

    引用传递时整个Java的精髓所在, 核心意义:同一块堆内存空间可以被不同的栈内存所指向,不同栈内存可以对同一堆内存...

  • 引用传递

    。。。。。。

  • 6-对象引用分析

    引用传递分析     类本身属于引用数据类型,既然是引用数据类型,那么久牵扯到内存的引用传递,所谓的引用传递的本质...

  • 值传递&引用传递

    值传递: 方法调用时,实际参数把它的值传递给对应的形式参数,函数接收的是原始值的一个copy,此时内存中存在两个相...

网友评论

      本文标题:引用传递

      本文链接:https://www.haomeiwen.com/subject/fxsefftx.html