Java隐式指针解读
文章目录
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,0
和10,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);
}