Java隐式指针解读

版权声明: https://blog.csdn.net/pbrlovejava/article/details/82881526


Java有指针吗?

许多学习java的新手可能会认为java没有指针,加上许多java开发者对于这块偏底层的东西也没有过深入的了解,所以java没有指针这样的认识就产生了,但答案是,java有指针但是java开发者并不能像c++开发者一样直接去调用指针。本文将对java指针做一基本讲解。

相关概念

1、指针

指针(Pointer),即一块存储空间的内存地址,若给定了这个内存地址,则顺着这个内存地址就可以访问到相应的内存区域。
java中的指针被称为隐式指针,不能被直接操作;而在c++中,开发中可以直接操作指针,被称为显示指针

2、堆

堆(Heap),每一个对象被创建后,该对象的实例都会存放在堆中

3、栈

栈(Stack),存放对象相应的内存地址,即存放指针,每一个指针指向堆中的
相应对象实例。

4、共享内存

即一个内存地址(指针)被多个实例引用。

5、自动解引用

java 的点号表达式会自动解引用指针以用来访问或赋值数据域。

使用Java的隐式指针

创建一个矩形对象Rectangle
public class Rectangle {
    int x;//x轴坐标
    int y;//y轴坐标
    int width;//宽
    int height;//高


    public Rectangle(int x, int y, int width, int height) {
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;
    }

    public Rectangle() {
    }

}

首先,初始化Rectangle对象一个空参实例rect1和含参实例rect2,打印输出用以分析
 //初始化Rectangle对象
        Rectangle rect1 = new Rectangle();
        Rectangle rect2 = new Rectangle(10, 20, 35, 45);
        //打印对象观察
         //打印对象观察
        System.out.println("rect1->"+rect1.x+","+rect1.y+","+rect1.width+","+rect1.height
                +","+"----"+rect1);
        System.out.println("rect2->"+rect2.x+","+rect2.y+","+rect2.width+","+rect2.height
                +","+"----"+rect2);

在这里插入图片描述

内存图分析

可以看出,两个实例的数据分别初始化为了0,0,0,010,20,35,45,它们分别对应的内存地址是@1089e5f@141d797,画出内存图,如下,JVM为对象实例开辟了一块堆空间(heap space),并且为内存地址开辟了栈空间(stack space),其中的指针@xxx指向了两个对象实例
在这里插入图片描述

共享内存
	//初始化Rectangle对象
        Rectangle rect1 = new Rectangle();
        Rectangle rect2 = new Rectangle(10, 20, 35, 45);
        //打印对象观察
        System.out.println("rect1->"+rect1.x+","+rect1.y+","+rect1.width+","+rect1.height
                +","+"----"+rect1);
        System.out.println("rect2->"+rect2.x+","+rect2.y+","+rect2.width+","+rect2.height
                +","+"----"+rect2);
        //将rect2的内存引用“复制给rect1”,此时rect1和rect2指向同一内存空间
        //rect1的原内存被gc
        rect1 = rect2;
        //打印rect1
        System.out.println("rect1->"+rect1.x+","+rect1.y+","+rect1.width+","+rect1.height
                +","+"----"+rect1);
        //比较内存地址
        System.out.print("内存地址比较结果->");
        System.out.println(rect1 == rect2);

rect1 = rect2,将rect2的内存地址共享给了rect1,数据域也进行了更改,此时内存图如下

内存图分析

在这里插入图片描述

此时,执行程序,rect1和rect2的指针是同一个,使用==比较指针地址,应该返回true
在这里插入图片描述

数据同步

其实,上面的程序已经在操作隐式指针了,rect1=rect2就是将指针共享,这时修改rect2的数据域,由于rect1引用了rect2的内存,所以rect1数据会同步修改

//初始化Rectangle对象
        Rectangle rect1 = new Rectangle();
        Rectangle rect2 = new Rectangle(10, 20, 35, 45);
        //打印对象观察
        System.out.println("rect1->"+rect1.x+","+rect1.y+","+rect1.width+","+rect1.height
                +","+"----"+rect1);
        System.out.println("rect2->"+rect2.x+","+rect2.y+","+rect2.width+","+rect2.height
                +","+"----"+rect2);
        //将rect2的内存引用“复制给rect1”,此时rect1和rect2指向同一内存空间
        //rect1的原内存被gc
        rect1 = rect2;
        //打印rect1
        System.out.println("rect1->"+rect1.x+","+rect1.y+","+rect1.width+","+rect1.height
                +","+"----"+rect1);
        //比较内存地址
        System.out.print("内存地址比较结果->");
        System.out.println(rect1 == rect2);
        //修改rect2的数据,rect1的数据也改变,说明指向同一内存空间
        rect2.x = 30;
        System.out.println("rect1->"+rect1.x+","+rect1.y+","+rect1.width+","+rect1.height
                +","+"----"+rect1);
        System.out.println("rect2->"+rect2.x+","+rect2.y+","+rect2.width+","+rect2.height
                +","+"----"+rect2);

    }

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/pbrlovejava/article/details/82881526
今日推荐