初学Java时,在很长一段时间里,总觉得基本概念很模糊。后来才知道,在许多Java书中,把对象和对象的引用混为一谈。可是,如果我分不清对象与对象引用,那实在没法很好地理解下面的面向对象技术。把自己的一点认识写下来,或许能让初学Java的朋友们少走一点弯路。 为便于说明,我们先定义一个简单的类:
class Vehicle { int passengers; int fuelcap; int mpg; }
有了这个模板,就可以用它来创建对象:
Vehicle veh1 = new Vehicle();
通常把这条语句的动作称之为创建一个对象,其实,它包含了四个动作: 1)右边的“new Vehicle”,是以Vehicle类为模板,在堆空间里创建一个Vehicle类对象(也简称为Vehicle对象)。 2)末尾的()意味着,在对象创建后,立即调用Vehicle类的构造函数,对刚生成的对象进行初始化。构造函数是肯定有的。如果你没写,Java会给你补上一个默认的构造函数。 3)左边的“Vehicle veh1”创建了一个Vehicle类引用变量。所谓Vehicle类引用,就是以后可以用来指向Vehicle对象的对象引用。 4)“=”操作符使对象引用指向刚创建的那个Vehicle对象。 我们可以把这条语句拆成两部分:
Vehicle veh1; veh1 = new Vehicle();
效果是一样的。这样写,就比较清楚了,有两个实体:一是对象引用变量,一是对象本身。 在堆空间里创建的实体,与在数据段以及栈空间里创建的实体不同。尽管它们也是确确实实存在的实体,但是,我们看不见,也摸不着。不仅如此,我们仔细研究一下第二句,找找刚创建的对象叫什么名字?有人说,它叫“Vehicle”。不对,“Vehicle”是类(对象的创建模板)的名字。一个Vehicle类可以据此创建出无数个对象,这些对象不可能全叫“Vehicle”。 对象连名都没有,没法直接访问它。我们只能通过对象引用来间接访问对象。 为了形象地说明对象、引用及它们之间的关系,可以做一个或许不很妥当的比喻。对象好比是一只很大的气球,大到我们抓不住它。引用变量是一根绳,可以用来系汽球。 如果只执行了第一条语句,还没执行第二条,此时创建的引用变量veh1还没指向任何一个对象,它的值是null。引用变量可以指向某个对象,或者为null。它是一根绳,一根还没有系上任何一个汽球的绳。执行了第二句后,一只新汽球做出来了,并被系在veh1这根绳上。我们抓住这根绳,就等于抓住了那只汽球。 再来一句:
Vehicle veh2;
就又做了一根绳,还没系上汽球。如果再加一句:
veh2 = veh1;
系上了。这里,发生了复制行为。但是,要说明的是,对象本身并没有被复制,被复制的只是对象引用。结果是,veh2也指向了veh1所指向的对象。两根绳系的是同一只汽球。 如果用下句再创建一个对象:
veh2 = new Vehicle();
则引用变量veh2改指向第二个对象。 从以上叙述再推演下去,我们可以获得以下结论:(1)一个对象引用可以指向0个或1个对象(一根绳子可以不系汽球,也可以系一个汽球);(2)一个对象可以有N个引用指向它(可以有N条绳子系住一个汽球)。 如果再来下面语句:
veh1 = veh2;
按上面的推断,veh1也指向了第二个对象。这个没问题。问题是第一个对象呢?没有一条绳子系住它,它飞了。多数书里说,它被Java的垃圾回收机制回收了。这不确切。正确地说,它已成为垃圾回收机制的处理对象。至于什么时候真正被回收,那要看垃圾回收机制的心情了。 由此看来,下面的语句应该不合法吧?至少是没用的吧?
new Vehicle();
不对。它是合法的,而且可用的。譬如,如果我们仅仅为了打印而生成一个对象,就不需要用引用变量来系住它。最常见的就是打印字符串:
System.out.println(“I am Java!”);
字符串对象“I am Java!”在打印后即被丢弃。有人把这种对象称之为临时对象。 对象与引用的关系将持续到对象回收。但是,关于这一点,打算在下文“简述Java回收机制”再说。
文章来源:http://blog.csdn.net/beepbug/archive/2006/08/14/1062790.aspx
分享到:
相关推荐
首先,我们需要理解什么是Java对象。在Java中,对象是类的实例。当我们使用`new`关键字创建一个类的实例时,就创建了一个对象。对象包含了数据(称为属性或成员变量)和行为(称为方法)。例如,如果我们有一个名为`...
本文将从以下几个方面详细解析对象与引用的基本概念及其相互间的关系。 #### 一、对象与引用的基础概念 **对象**: 在Java中,对象是类的一个实例,即根据类的模板创建出来的具体实体。每个对象都有自己的属性(如...
MAT可以提供详细的内存报告,显示每个对象及其引用链的大小。另一个例子是`Apache Commons Lang`的`ClassUtils`,提供了一个`estimateSize`方法来估算对象大小。 3. **手动计算**:开发者也可以手动计算,根据对象...
Heap Dump是Java虚拟机(JVM)在特定时刻对内存快照的记录,包含了所有Java对象及其引用关系。通过分析这些信息,我们可以识别哪些对象占用大量内存,以及对象之间的引用链,从而找出可能的内存泄漏源。 IBM JAVA ...
### Java对象池技术的原理及其实现 #### 摘要 本文深入探讨了Java对象池技术的基本原理及其实现方式,旨在帮助读者理解如何利用对象池优化Java应用程序的性能。通过对对象池技术核心概念——缓存与共享的阐述,本文...
#### Java对象及其引用 **定义类与创建对象** - **定义类**:类是具有相同属性和行为的对象的模板。 - **创建对象**:通过`new`关键字创建类的实例,实例化后,每个对象在堆内存中都有一个唯一的地址。 **代码...
2. **Java对象及其引用**: - 弱引用、软引用和虚引用等不同类型的引用可以用于管理内存。 - 引用队列可以用来跟踪引用对象的状态变化。 3. **虚拟机自动垃圾回收机制**: - 垃圾回收器负责回收不再使用的对象所...
Java是一种广泛使用的面向对象...通过阅读`java基础.txt`、`java基础知识.txt`、`Java新手入门的30个基本概念.txt`和`Java对象及其引用.txt`这些文档,相信你可以系统地掌握Java的基石,为后续的进阶学习打下坚实基础。
使用这个库,你可以很容易地计算出一个对象及其所有嵌套引用的对象的总大小。然而,这个库并不是标准Java库的一部分,所以你需要将其引入到项目中。 如果你不想引入额外的依赖,可以自己编写一个简单的工具类来实现...
Java对象在内存中的结构及其生命周期是Java编程中基础且关键的概念。Java的内存管理主要涉及栈(Stack)和堆(Heap)两个区域,对于理解程序的性能和内存使用至关重要。 首先,栈主要用于存储基本数据类型(如int, ...
本文将深入探讨Java中的引用以及对象的克隆机制,包括浅拷贝和深拷贝的区别及其应用场景。 #### 二、Java中的引用 在Java中,当使用`new`关键字创建一个对象时,实际上创建的是一个指向该对象的引用。例如,以下...
本篇文章将详细探讨Java中的对象克隆及其实现方式。 一、浅克隆与深克隆 在Java中,克隆分为两种类型:浅克隆(Shallow Clone)和深克隆(Deep Clone)。浅克隆创建的新对象只复制了原对象的引用,这意味着如果原...
### Java对象序列化标准知识点详解 #### 一、系统架构概览 **1.1 概览** Java 对象序列化是一种将Java对象的状态转换成字节流的过程,以便于在网络上传输或存储到磁盘上。Java序列化标准定义了一套规则来描述如何...
运行时多态则是通过父类引用指向子类对象,调用子类覆盖的父类方法,实现动态绑定。 面向对象编程的起点是抽象,我们需要识别现实世界中的对象和它们的属性、行为,然后通过定义类来抽象这些实体。在Java中,类定义...
这里的“java不同对象之间及集合的复制”主要关注如何高效且便捷地完成对象及其集合的复制工作,避免繁琐的手动赋值。描述中提到的“model VO值复制注解”提供了一种自动化的方法,使得复制过程更加简洁和灵活。 1....
通过运行这个示例,开发者可以了解到Java对象在内存中是如何表示的,包括对象头、实例变量和引用的大小。这对于理解和优化Java应用的内存使用情况至关重要,尤其是在处理大量对象或者需要精确控制内存分配的场景下。...
观看这个视频可以更直观地理解匿名对象的概念及其用法,从而加深对Java面向对象编程的理解。 总结来说,匿名对象是Java中一种独特的编程技巧,它简化了代码,减少了不必要的变量声明,尤其在短暂使用对象或实现简单...
Java作为一门强大的面向对象编程语言,在实际开发过程中,对象的创建及其内存管理是至关重要的环节。深入理解对象在内存中的分配过程不仅能够帮助开发者设计出更为高效合理的程序,还能够在一定程度上提升程序的性能...
"Java对象池策略及其性能的研究" Java对象池策略是指当对象池内的对象数量已经达到上限,但有新的对象要加入时,需按照某种算法从对象池选择一个删除,以便添加新的对象。常用的策略有LRU策略、轮询策略和随机策略...
8. **集合框架**:Java集合框架包括List、Set、Map等接口及其实现类,如ArrayList、HashSet、HashMap等。学习者需要理解它们的特点和使用场景。 9. **接口与抽象类的区别**:接口完全是抽象的,不包含任何方法实现...