Java-自学-7
指针(pointer)
老师用了一个很巧妙的例子引出指针,这个真的是国内教材中学不到的东西,那么我们来看看这个例子吧(神秘海象)
public class Walrus{
double W_weight;
double W_age;
/** construtor 1 */
public Walrus(double weight, double age){
W_weight = weight;
W_age = age;
}
constructor 1,用于对Walrus类进行参数的设定。
/** constructor 2 */
public Walrus(Walrus a){
}
constructor 2, 也就是我们神秘海象的故事的开始,我们直接使用了Walrus(Walrus a)语句。而这个语句究竟是什么意思呢,我们先往下看:
public static void main(String[] args){
Walrus a = new Walrus(1000, 8.3);
Walrus b = a;
b.W_weight = 5;
System.out.println(a.W_weight);
System.out.println(b.W_weight);
}
OK,如上述程序所示,我们用a = new Walrus(1000, 8.3);创造了a,然后令b = a,并且改变b中W_weight的值。
那么问题来了,我们输出的结果,a是否会改变呢?
a的值也改变了,也随着b.W_weight = 5;变成了5!难道赋值语句也会使赋值的对象产生改变?
那么我们来看下一个极其简单的例子:
int c = 5;
int d = c;
d = 3;
System.out.println(c);
System.out.println(d);
难道这种情况下c的值也会改变吗???
还好还好,并没有。那问题就出现了,为什么我们的赋值语句在两种情况下出现了如此不同的结果呢。下面我们一点一点来分析:
在Java中,存在一种类型称为primitive type,其中包含:int, short, long, float, double, char, byte, boolean。这些是Java中本身就含有的type,我们通过不同的type分配给对应的参数不同的空间。i.e. int a; 我们为a在电脑存储器中开辟出32bits的存储空间;double a; 我们为a在电脑存储空间开辟出64bits的空间。因此当我们输入以下语句:
int c;
int d;
在内存中实际发生的事情是这样的:
推荐网站https://cscircles.cemc.uwaterloo.ca/java_visualize,让你的程序也可视化吧!
我们可以看到存储器中分别为c、d开辟了32bits的空间,而我们对b进行修改时,自然不会影响到a的结果。
那么在Java中,还有另一种type称为reference type。这种类型就值得深挖了,首先我们来看看一个单纯的小海狮有着怎么样的表现:
Walrus(1000, 8.3)
它在存储空间中建立了一个列表,double W_weight创建了一个64bits double类型的参数,用于存储其对应的值,同样W_age也一样创建了一个64bits double类型的参数存储对应值。
那么接下来就是见证奇迹的时刻了:
Walrus a = new Walrus(1000, 8.3);
这句话究竟做了什么呢?
我们通过new,创建了一个reference type!所以a与我们通常看到的int,double这种类有所不同了,在这里,a创建了一个空间,而这个空间做了什么呢,我们来看看下面的图:
这里的箭头代表着什么呢——地址,我们的a中存储的是一个地址,这个地址指向了Walrus!那么此时我们再看这个语句:
a = b;
这里实际上是b拷贝了a中的值,而这个值实质上是Walrus的地址,而当我们对b中的参数b.W_weight进行修改时,实际上是顺着地址找过去,修改了Walrus中的值,如下图所示:
这就是为什么我们修改b的数值时a变化的原因。
**而我们在这里就有了个新的定义,对于a、b这种存储着指向存储单元中某段数据的地址的变量,我们能给它们起个名字,叫指针(pointer)**这种参数存储的是我们所需要的内容的地址。