java的对象与对象引用

第一次接触到引用这个词,是在《Thinking in JAVA》中。当时没有接触c++,

看到引用这个词不敏感,就想只把它当作一个普通的名词,习惯就好。

然而最近开始学习c++,才知道原来引用这个词,早先在c++里,就已经

有了特别的含义。而《Thinking in JAVA》的作者Bruce Eckel选择引用这个词

的原因,就是因为其与c++的引用功能的相似性。今天找了一些资料学习了

一下,也算是对引用这个词有了新的理解。

那么在java中,对象引用是什么呢?

先来看一段代码

class TestClass {
  public int tag;
  public TestClass() {}
}

public class Test {
  public static void main(String[] args) {
    TestClass tc = new TestClass();
  }
}

在main方法中,我new了一个TestClass。于是我现在可以这么说,

我new了一个TestClass的对象。new是在堆里开辟了一块空间来存放这个对象,

所以我的

这个TestClass对象就在堆里。那我怎么去操作它呢?这时候就需要用到对象

引用了。比如我现在不喜欢这个对象的tag值,我要修改它,就改为1吧,那么我

所能做的就是 tc.tag = 1; (这里为了方便,我直接将tag写成public)除此之外,

还有别的方法去改吗?没有了,我不可能直接给这个对象说“喂,把你的值改

为1”,然后它就变为1了吧。这就是对象引用!我们通过它去操作那些new出来的对象。

现在我把我之前那段代码做一些细微的改动

class TestClass {
  public int tag;
  public TestClass() {}
}

public class Test {
  public static void main(String[] args) {
    TestClass tc = new TestClass();
    new TestClass();
  }
}

看出什么变化了吗?对,我只是紧接着又new了一个TestClass的新对象。然后呢?

我也不喜欢它的tag,我想把它改为33。怎么改?改不了。刚new完以后它就失去了

制,从我手中丢掉了。我现在唯一能做的,就是等着垃圾回收器检测到并且销毁它。

现在有没有感觉有清晰了一点,举两个例子可能更容易理解一点。
eg1:我在街上先碰到了一个孩子(这就是我的第一个TestClass对象),

我答应他,如果他把名字告诉我并且跟我走,就给他一颗糖
(这就相当于TestClass tc = new TestClass();),然后他就告诉我他的名字叫tc,

并且我记住了。走到一个分叉路口时,我想让他走第1个路口,就跟他

说“tc,咱们走第一个路口”(tc.tag = 1;)。走着走着又遇到了第二个孩子,我同样给了

他一颗糖又让他跟我走,但是此时我就忘了问他的名字(此时就相当于new TestClass();),

着走着又到了第二个分叉路口,此时我想带着他们俩走第33个路口,此时我能对tc说

“tc,咱们这次走第三十三个路口”,但是第二个孩子呢?我叫不出他的名字,甚至在拥挤的人群中,

我都找不到他在哪里,也没法找,最后结果就是他吃了我的糖就走了。(即最后被垃圾回收器回收)。

eg2:比如这个TestClass类是美的的型号为(ABC-XYZ)的空调。然后我想去买一台,于是我就跑

到商场里买了一台。付了钱以后,商场把空调遥控器给我了,我就回家吹空调去了。如果用tag来表示

它的温度,那么此时我觉得这个温度太冷了,我想调高一点,就25°吧。于是我就拿起遥控器,将温度

调到了25°。此时这个遥控器就是我的对象引用tc,而空调就是我new出来的那个TestClass对象。

那TestClass类是什么呢?可以说它是空调的设计图,或者是一个模板。照着它设计出的空调都一模一样

每当我new了一个对象,就是照着这个模板生产出了一台新空调。之后我吹空调吹着吹着又觉得不够用,

还得去再买一台,于是我又跑到商场再买一台挂到墙上。但是这次我把最重要的一个东西——遥控器忘了。

没拿遥控器怎么办?什么也办不了,就只能痴痴望着空调发呆。事后去要遥控器还要不到。怎么办?只能

过几天找工人来给它卸掉,装在那里也是浪费地方(垃圾回收器自动回收),要用大不了我再买个

(这次记得要遥控器);

到这里应该有一个很清晰的认识了吧。对象就是挂在墙上的空调(在堆里开辟的空间),对象引用

就是握在你手里的遥控器。没有遥控器你只能干看着,为了不占空间,过几天还要找人把它给卸掉。

但是只有遥控器你还是没用,你对着墙壁发指令?

但是说起来它们的关系也不是严格的一一对应。我把之前的代码又再改改

class TestClass {
  public int tag;
  public TestClass() {}
}

public class Test {
  public static void main(String[] args) {
    TestClass tc = new TestClass();
    TestClass tc2 = new TestClass();
    /*
        TestClass tc3;
        tc3 = tc; tc = tc2; tc2 = tc3;
    */
  }
}

这次我两个对象都有了对象引用,但是并不是tc就只能一直是第一个对象的引用,它也能是第二个

对象的引用,加上注释里的代码,我就实现了两个对象的引用的交换。可能这样没什么感觉,但是

如果你能看到堆内存的变化,你就会突然明了。甚至同一个对象能同时拥有多个对象引用。如果我

的注释里四句语句只要前面两句,那么我的tc和tc3都将是第一个对象的对象引用。当我执行

完tc3.tag = 5;后,再输出tc.tag,那么此时输出的将是5,而不再是上面的1。但是有一点,一个对象

引用却只能被一个对象所拥有。这一点我非常肯定我不用解释了。

以上就是我对对象引用的一些认识,写出来除了自己巩固一次,也希望能给一些迷惑的朋友一些帮助,

如果有什么不正确的,也欢迎大家给我指出来。

你可能感兴趣的:(java)