对象引用和对象

初学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回收机制”再说。

时间: 2024-10-06 00:43:12

对象引用和对象的相关文章

简述对象引用和对象的区别

在做机房的时候,遇到最多的问题就是"未将对象引用添加到对象实例".每次遇到这样的问题,我一直在想:我在类中明明实例化类了,为什么还会出现这样的问题?还有"对象引用"什么意思?带着这些问题从网上查了一些关于对象引用和对象的知识,现做一下总结: 现在有一个类ClassA,对它进行实例化的过程如下: '方法一 Dim a = New ClassaA() '方法二 Dim a as ClassA a= New ClassA() 有一段时间,我认为这是实例化类的方法之一,其实

对象引用与对象克隆

对象克隆就是在原先对象的基础上,再复制一份,克隆的属性与原先的一模一样,但是是两个对象,之后对这两个对象的任何操作都不会影响到对方.要想将某个对象克隆,必须实现Cloneable接口,然后还需要复写Object类的clone方法. 对象引用其实是多个索引对同一个对象的引用,不管谁改变了对象的属性,对象都会改变,其他索引再访问时,属性已经变了 像函数式编程,对象的操作都是无副作用的,不会改变对象的状态,类似于对象克隆,就是把对象再复制一份,原先的对象不动,只需要使用复制的那个对象即可.而原始的ja

java对象引用和对象值得行为

关于java对象和传值得问题,偶然间在看js的时候,发现的一个无效转换对象数据的问题,自己感觉有点疑惑,以为是js的特性,随机想在java上面证实一下,结果发现并不是js的特性,java也是如此然后查了些许资料发现自己学习的疏忽,当时确实惊出了一身冷汗呀,现在就具体说下问题: 在做值转换的时候碰到了如下情况 示例1: public static void intValueChange(int a,int b){ int temp = a; a = b; b = temp; System.out.

不存在继承关系各类中、不存在对象引用的对象创建初始化顺序

实例3 class One   {        One(String str)      {        System.out.println(str);       }    } class Two   {       One one_1 = new One("one-1");       One one_2 = new One("one-2");       One one_3 = new One("one-3");      Two(S

Java --对象引用与对象的区别

最近做项目时,遇到了一个错误: public class UserJobFilteredServiceImpl implements UserJobFilteredService {          //方法1,业务方法,实现service层的方法     public void getAttention(int userId) {         //这个方法里面需要调用方法2,我采用如下方式调用,运行时报错         UserJobFilteredServiceImpl  userJ

Java 并发编程(二)对象的不变性和安全的发布对象

一.不变性 满足同步需求的另一种方法是使用不可变对象(Immutable Object).到目前为止,我们介绍了许多与原子性和可见性相关的问题,例如得到失效数据,丢失更新操作或光查到某个对象处于不一致的状态等等,都与多线程视图同时访问同一个可变的状态相关.如果对象的状态不会改变,那么这些问题与复杂性也就自然消失了. 如果某个对象在被创建后其状态就不能被修改,那么这个对象就被成为不可变对象.线程安全型是不可变对象的固有属性之一,他们的不变性条件是由构造函数创建的,只要他们的状态不改变,那么这些不变

一入python深似海--变量和对象

一.基本原理 Python中一切都是对象,变量是对象的引用.这是一个普遍的法则.我们举个例子来说,Python是如何来处理的. x = 'blue' y = 'green' z = x 当python执行上面第一句的时候,会在heap中首先创建一个str对象,其文本内容为blue,同时还创建一个名为x的对象引用,x引用的就是这个str对象.第二句也是类似:第三条创建了一个名为z的新对象引用,并将其设置为对象引用x所指向的相同对象.如下图的变化. 所以看出在Python中赋值操作符号"="

db4o这个对象数据库有很多优点,但为什么不是很火? 大家有没有用过db4o的?

没有主键的概念(因为对象的内存地址,或者引用就能标志一个对象了).因而外界想指向一个具体的对象就比较困难(比如本页的url里的1079505). 激活/保存层次的问题.获取一个对象,它的字段引用了其它对象,那么到底激活多少层次合适?保存时也是如此.层次深了伤性能,层次浅了用着不方便(动不动就是Null reference). 对象引用问题.RDBMS里我们能很轻易地明白一个引用指向的是对象的浅拷贝(因为只引用了一个主键).而一旦与内存中的对象勾搭起来,那深拷贝和浅拷贝就不容易区分了,很难说清我删

jhat中的OQL(对象查询语言)

http://blog.csdn.net/wanglha/article/details/40181767 jhat中的OQL(对象查询语言) 如果需要根据某些条件来过滤或查询堆的对象,这是可能的,可以在jhat的html页面中执行OQL,来查询符合条件的对象 基本语法: select <JavaScript expression to select>[from [instanceof] <class name> <identifier>][where <java