原文地址:

http://www.cnblogs.com/dolphin0520/p/3592498.html

在Java中,有一组名词经常一起出现,它们就是“对象和对象引用”,很多朋友在初学Java的时候可能经常会混淆这2个概念,觉得它们是一回事,事实上则不然。今天我们就来一起了解一下对象和对象引用之间的区别和联系。

1.何谓对象?

  在Java中有一句比较流行的话,叫做“万物皆对象”,这是Java语言设计之初的理念之一。要理解什么是对象,需要跟类一起结合起来理解。下面这段话引自《Java编程思想》中的一段原话:

  “按照通俗的说法,每个对象都是某个类(class)的一个实例(instance),这里,‘类’就是‘类型’的同义词。”

  从这一句话就可以理解到对象的本质,简而言之,它就是类的实例,比如所有的人统称为“人类”,这里的“人类”就是一个类(物种的一种类型),而具体到每个人,比如张三这个人,它就是对象,就是“人类”的实例。

2.何谓对象引用?

  我们先看一段话:

  “每种编程语言都有自己的数据处理方式。有些时候,程序员必须注意将要处理的数据是什么类型。你是直接操纵元素,还是用某种基于特殊语法的间接表示(例如C/C++里的指针)来操作对象。所有这些在 Java 里都得到了简化,一切都被视为对象。因此,我们可采用一种统一的语法。尽管将一切都“看作”对象,但操纵的标识符实际是指向一个对象的“引用”(reference)。”  

  这段话来自于《Java编程思想》,很显然,从这段话可以看出对象和对象引用不是一回事,是两个完全不同的概念。举个例子,我们通常会用下面这一行代码来创建一个对象:

Person person = new Person("张三");

有人会说,这里的person是一个对象,是Person类的一个实例。

也有人会说,这里的person并不是真正的对象,而是指向所创建的对象的引用。

到底哪种说法是对的?我们先不急着纠结哪种说法是对的,再看两行代码:

Person person;
person = new Person("张三");

这两行代码实现的功能和上面的一行代码是完全一样的。大家都知道,在Java中new是用来在堆上创建对象用的,如果person是一个对象的话,那么第二行为何还要通过new来创建对象呢?由此可见,person并不是所创建的对象,是什么?上面的一段话说的很清楚,“操纵的标识符实际是指向一个对象的引用”,也就是说person是一个引用,是指向一个可以指向Person类的对象的引用。真正创建对象的语句是右边的new Person("张三");

再看一个例子:

Person person;
person = new Person("张三");
person = new Person("李四");

这里让person先指向了“张三”这个对象,然后又指向了“李四”这个对象。也就是说,Person person,这句话只是声明了一个Person类的引用,它可以指向任何Person类的实例。这个道理就和下面这段代码一样:

int a;
a=2;
a=3;

这里先声明了一个int类型的变量a,先对a赋值为2,后面又赋值为3.也就是说int类型的变量a,可以让它的值为2,也可以为3,只要是合法的int类型的数值即可。

也就是说,一个引用可以指向多个对象,而一个对象可不可以被多个引用所指呢?答案当然是可以的。

比如:

Person person1 = new Person("张三");
Person person2 = person1;

person1和person2都指向了“张三”这个对象。   

关于对象和对象引用的区别和联系暂时就讲这么多了,感兴趣的朋友可以查阅相关文档和资料。

下面部分

原文地址:

https://my.oschina.net/u/2312022/blog/500599?p={{currentPage+1}}

为了便于理解,先定义一个简单的类

class User{
int userId;
String userName;
String age;
}

有了如上类,我们便可以创建对象,如下:

User user1 = new User();

创建对象的过程中包含了如下几个动作

1>右边的new User,是以User类为模板,在堆空间里创建一个User类的对象。

2>末尾()表示,在对象创建后,立即调用User类的构造函数,对刚生成的对象进行初始化。(构造函数是肯定有的,如果我们没写,系统会自动生成一个构造函数)

3>左边的User user1,是创建了一个User类的引用变量。

4>=操作符使对象引用指向刚刚建好的User对象

其实,可以将如上步骤分为两步

1>User user1;

2>user1=new User();

这样写就比较清楚了,有两个实体:一个是对象引用变量,一个是对象本身。

举个很生动的例子:对象好比一个气球,引用变量是一根绳,可以用来系气球。

如果只是执行了第一条语句,还没执行第二条,此时创建的引用变量user1还没指向任何一个对象,它的值是null,引用变量是一根还没有系上气球的绳;

当执行了第二句后,一只新气球做出来了,并被系在user1这根绳上。

再来一句

User user2;

此时又做了一根绳子,还没系上气球,接着来一句

user2 = user1;

此时,发生了复制行为。注意:对象本身没有被复制,被复制的是对象引用。结果是user2也指向了user1所指向的对象,即两根绳子都系上同一个气球了。

如果在创建一个对象

user2 = new User();

此时,引用变量user2改指向了第二个对象。

由如上例子,我们得出结论:

1>一个对象引用可以指向0个或1个对象(形象解释:一根绳子可以不系气球,也可以系一个气球)

2>一个对象可以有N个引用指向它(解释:可以有N条绳子系住同一个气球)

如果再来一句

user1 =user2;

即是 user1也指向了第二个对象。这个是没问题的,问题是第一个对象呢?没有一条绳子系住它,它可能会飞。正确说来,它已成为jav的垃圾回收机制处理对象了,至于什么时候被回收,这处决于java回收机制了。

由此看来,下面的语句应该是不合法的,至少应该没用

new User();

书上介绍说,它是合法的,而且是可用的,比如,我们仅仅为了打印而生成一个对象,就不需要引用变量来系住它,最常见的就是打印字符串:

System.out.println("I am java");

字符串对象"I am java"在打印后就被丢掉。有人称之为这种对象为临时对象。

(转)浅谈Java中的对象和对象引用的更多相关文章

  1. 浅谈Java中的对象和对象引用

    浅谈Java中的对象和对象引用 在Java中,有一组名词经常一起出现,它们就是“对象和对象引用”,很多朋友在初学Java的时候可能经常会混淆这2个概念,觉得它们是一回事,事实上则不然.今天我们就来一起 ...

  2. 浅谈Java中的对象和引用

    浅谈Java中的对象和对象引用 在Java中,有一组名词经常一起出现,它们就是“对象和对象引用”,很多朋友在初学Java的时候可能经常会混淆这2个概念,觉得它们是一回事,事实上则不然.今天我们就来一起 ...

  3. 浅谈Java中的equals和==(转)

    浅谈Java中的equals和== 在初学Java时,可能会经常碰到下面的代码: 1 String str1 = new String("hello"); 2 String str ...

  4. 浅谈Java中的equals和==

    浅谈Java中的equals和== 在初学Java时,可能会经常碰到下面的代码: String str1 = new String("hello"); String str2 = ...

  5. 浅谈Java中的深拷贝和浅拷贝(转载)

    浅谈Java中的深拷贝和浅拷贝(转载) 原文链接: http://blog.csdn.net/tounaobun/article/details/8491392 假如说你想复制一个简单变量.很简单: ...

  6. 浅谈Java中的深拷贝和浅拷贝

    转载: 浅谈Java中的深拷贝和浅拷贝 假如说你想复制一个简单变量.很简单: int apples = 5; int pears = apples; 不仅仅是int类型,其它七种原始数据类型(bool ...

  7. 【转】浅谈Java中的hashcode方法(这个demo可以多看看)

    浅谈Java中的hashcode方法 哈希表这个数据结构想必大多数人都不陌生,而且在很多地方都会利用到hash表来提高查找效率.在Java的Object类中有一个方法: public native i ...

  8. 浅谈Java中的final关键字

    浅谈Java中的final关键字 谈到final关键字,想必很多人都不陌生,在使用匿名内部类的时候可能会经常用到final关键字.另外,Java中的String类就是一个final类,那么今天我们就来 ...

  9. 【转】浅谈Java中的hashcode方法

    哈希表这个数据结构想必大多数人都不陌生,而且在很多地方都会利用到hash表来提高查找效率.在Java的Object类中有一个方法: public native int hashCode(); 根据这个 ...

随机推荐

  1. Electron安装

    1.安装nodejs和npm 官网下载地址:https://nodejs.org/en/download/ 安装包:下载.msi 安装完成后: nodejs.npm都会安装好,path环境变量也自动设 ...

  2. DDD实践切入点(一)

    前两篇:大型系统的支撑,应用系统开发思想的变迁 之前大致说了使用DDD的前期准备,现在可以真正开始实践了,以我刚刚结束的一个简单的经典DDD方式的项目为例子,当然由于比较简单,所以很多时候会脱离它来介 ...

  3. ASP.NET Core的配置(5):配置的同步[设计篇]

    本节所谓的"配置同步"主要体现在两个方面:其一,如何监控配置源并在其变化的时候自动加载其数据,其目的是让应用中通过Configuration对象承载的配置与配置源的数据同步:其二. ...

  4. 初探AngularJS

    一.前言 早已听说AngularJS的大名,并在很久前也编写过些小demo,但是都没有系统学习过.由于,在下个版本项目中用到了AngularJS,so,那就一起再来研究研究呗. 说到,这个Angula ...

  5. Oracle 集群】ORACLE DATABASE 11G RAC 知识图文详细教程之ORACLE集群概念和原理(二)

    ORACLE集群概念和原理(二) 概述:写下本文档的初衷和动力,来源于上篇的<oracle基本操作手册>.oracle基本操作手册是作者研一假期对oracle基础知识学习的汇总.然后形成体 ...

  6. Java 计算N阶乘末尾0的个数-LeetCode 172 Factorial Trailing Zeroes

    题目 Given an integer n, return the number of trailing zeroes in n!. Note: Your solution should be in ...

  7. SQL连接

    SQL连接可以分为内连接.外连接.交叉连接. 数据库数据:             book表                                          stu表 1.内连接 ...

  8. 匹夫细说C#:委托的简化语法,聊聊匿名方法和闭包

    0x00 前言 通过上一篇博客<匹夫细说C#:庖丁解牛聊委托,那些编译器藏的和U3D给的>的内容,我们实现了使用委托来构建我们自己的消息系统的过程.但是在日常的开发中,仍然有很多开发者因为 ...

  9. Spark 入门

    Spark 入门 目录 一. 1. 2. 3. 二. 三. 1. 2. 3. (1) (2) (3) 4. 5. 四. 1. 2. 3. 4. 5. 五.         Spark Shell使用 ...

  10. C# http

    minihttpd minihttpd:HTTPWeb服务器库 https://www.codeproject.com/articles/11342/minihttpd-an-http-web-ser ...