学习Java,你必须分清对象和对象引用!

学习Java,你必须分清对象和对象引用!

今天要说的对象和对象引用,我觉得是非常重要的一个知识点,而且,学习java,你必须搞清楚这两个概念,真的很重要!

学习Java,你必须分清对象和对象引用!

庆哥:

你知道什么是对象吗?

小白:

对象?女朋友吗?

学习Java,你必须分清对象和对象引用!

庆哥:

唉,好无奈啊,毕竟我不是单身狗,我是说面向对象语言中的对象,也就是编程中的对象。

小白:

没有对象也不是我的错啊,毕竟我是一个单身贵族,你说的那个对象啊,我们学习java的都知道一句话,那就是“万物皆对象啊”

庆哥:

是的,在java中我们应该都听过这句话,在《java编程思想》这本书中是这样描述这句话的:“将对象视为奇特的变量,它可以存储数据,除此之外,你还可以要求它在自身上执行操作。理论上讲,你可以抽象待求解问题的任何概念化构件(狗,建筑物,服务等),将其表示为程序中的对象。”

小白:

是不是可以简单点说,java对象就是一类事物的抽象化,然后这个对象有自己的状态,行为和标识等,说白点就是这对象有自己的一些特征以及它可以干点啥。

庆哥:

你这样理解我丝毫不反对,而且觉得你说的还挺不错,那么我们就开始今天的问题吧,你知道什么是对象了,那么什么又是对象引用呢?

小白:

象引用?引用这个词我倒是经常听说,不过这个对象引用吗?倒还真是有点说不明白,心里大概知道,但是不知道该怎么表达,我觉得还是我不太明白。

学习Java,你必须分清对象和对象引用!

庆哥:

嗯,可以,我们慢慢来说这个对象引用,我们之前都学习过C语言吧,那你可还记得C语言中的指针,在C语言中,可以说指针是非常高深的东西,因为它可以直接操作内存,C语言也因为指针的存在而增加了不少的难度,我们简单的知道,指针可以指向一个物理地址,然后操作这一块的内存,那么什么是对象引用呢?

小白:

听你这样说,这java中的对象引用应该和指针是比较相似的了

庆哥:

是的,java中的对象引用是和C和C++中的指针是比较像的,但是也只是比较像而已,有人觉得java中的对象其实就是一个指针,但是实际上,java中的对象引用和C++中的引用在语法上更加接近,不过的java中的这个对象引用和C++中的引用也是存在巨大的差别的,在《java编程思想》第一版中把java中的对象引用叫做“句柄”,包括现在,我看有些文章在说java的对象引用的时候依然会说是句柄,不过,大家比较容易接受的还是引用这个词汇,所以在《java编程思想》的第二版中又改为大众普遍喜欢的“引用”

小白

竟然还有这知识,以前还不了解呢?

学习Java,你必须分清对象和对象引用!

庆哥:

我个人觉得吧,在《java编程思想》中有这么一段描述写的非常好:“每种编程语言都有自己的数据处理方式。有些时候,程序员必须注意将要处理的数据是什么类型。你是直接操纵元素,还是用某种基于特殊语法的间接表示(例如C/C++里的指针)来操作对象。所有这些在 Java 里都得到了简化,一切都被视为对象。因此,我们可采用一种统一的语法。尽管将一切都“看作”对象,但操纵的标识符实际是指向一个对象的“引用”(reference)。 ”,这句话就很好的解释了java中的对象引用,接下来我们简单看一个例子,先看下面的代码。

String s;

你看上面这简短的一句代码,如果我说,这里创建了一个String对象,你觉得我说的对吗?

小白

这个。。。我觉得好像不怎么对,要是创建一个String对象的话,应该是这样的吧

String s = new String();

因为一般创建一个对象都是使用new来创建啊,所以我不认为上面那句代码是创建了一个对象。

庆哥;

那么你觉得这句代码是在干什么呢?或者说它在完成什么?

小白:

这个,我猜这个s其实就是我们今天谈到的对象引用吧!

庆哥:

确实,其实这里的s就是一个对象引用,在《java编程思想》中举了这么一个例子,就是,什么是对象和对象引用呢?就好比,对象就像是一台电视机,而对象引用就是遥控器,遥控器是用来控制电视机了,遥控器与电视机是关联起来的,我们要控制整个电视机,只需要一个遥控器即可,同样,这里的s也只是创建了一个字符串引用而已,就相当于有了一个遥控器,可是这个时候没有电视机啊,可是记得不,还有万能遥控器啊,在没有进行配对之前,万能遥控器是不与任何一台电视机有关联的,当你配对之后他就与特定的电视机产生了管理,所以说这个s其实现在就是一个还没有指向任何字符串对象的字符串引用,当我们通过new的方式创建了一个字符串对象,其实就相当于给这个引用关联了一个对象,这个引用就指向了这个对象

小白:

学习Java,你必须分清对象和对象引用!

你这么一说,我突然就想到这么一段代码

String s = new String("hello");
String s1 = s;

对于上面的代码,s是一个字符串对象引用,那么下面的是不是就是相当于把s这个引用赋值给了s1,那么此时这个s是不是还指向这个字符串对象呢?也就是这个hello。

庆哥:

你这里其实是举了一个特例,你看看下面的代码

StringBuffer s = new StringBuffer("Java");  
  
StringBuffer s1 = s;  

你看看这段代码和你说的有什么区别?

小白

学习Java,你必须分清对象和对象引用!

什么玩意,有点懵逼啊!

庆哥:

这里其实要把握住的是对于String一旦创建其实是不可变得,我们再看下面的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Test {
   public static void main(String[] args) {
       String s = new String("hello");
       String s1 = s;
       s1 = "你好";
       System.out.println("s:" + s);
       System.out.println("s1:"+s1);
 
       StringBuffer s2 = new StringBuffer("Java");
       StringBuffer s3 = s2;
       s3.append("你好");
       System.out.println("s2:"+s2);
       System.out.println("s3:"+s3);
   }
}

 

学习Java,你必须分清对象和对象引用!

这是为什么呢?

小白

学习Java,你必须分清对象和对象引用!

庆哥:

这里记住的就是String其实是一个特例,之前s和s1指向的是同一个对象,但是当s1重新复制的话,所指向的对象就变了,这点对于StringBuffer不同,因为它创建的字符串存在于缓冲流,所以s2和s3一开始指向的是同一个对象,然后s3改变了这个对象,这个时候其实s2和s3指向的还是同一个对象,所以内容也是相同的,这里记住非常重要的一个知识点:如果两个引用指向同一个对象,那么不管哪个引用去改变这个对象,其结果是对象的内容都会发生改变,而且只有一个对象,但是记住了String是一个特例!

这下你明白了吗?

小白

学习Java,你必须分清对象和对象引用!

那今天就先到这里,明天会继续接着这个话题谈一谈java中的参数传递方式!

学习Java,你必须分清对象和对象引用!

 

发表评论