`

Java中实现对象比较的几个相关概念

阅读更多

Java中实现对象比较的几个相关概念(转)

一、跟对象比较的几个相关的概念

    为了更加深刻的理解对象比较的含义以及多个比较方法之间的差异,笔者认为读者首先需要了解几个相关的概念,或者说几对关系。

  一是类与对象的关系。类是具体的抽象,而对象是类的具体实现。这可能听起来还是有点模糊。做一个形象的比喻,类就好像是用来制作塑料盒子的模具,只要将PVC料注入到这个模具中就可以生产对应形状的盒子。而对象就好像是生产出来的盒子。虽然模具同一个,但是生产出来的盒子彼此之间仍然是不同的。一方面先天性就是不同的。因为根据相对论可以说明世界上没有两个相同的东西。其次后天性的影响,也会导致其不同。如生产出来后,在两个盒子上分别贴上不同的条码,他们两个就代表不同的盒子了。了解这个类与对象之间的关系,对于了解对象之间进行比较,会有很大的帮助。

  二是需要知道类与对象在内存中的实际存储情况。当程序员定义一个类时(不含有静态成员或者变量),一般不会在内存中给其分配一个存储结构。而只有定义对象时,才会在内存中分配存储结构。当利用同一个类定义不同的对象时,系统会在内存中为不同的对象创建不同的存储结构。也就是说,会对应不同的内存地址。虽然同一个类中定义出来的对象,其内容可能相同(成员变量、成员方法等等都相同),但是其内存中的地址仍然是不同的。

  三是需要注意对象的复制问题。如果要创建几个内容相同的对象,即复制相同内容的对象,现在主要有两种方法。一是通过成员变量赋值来完成。如在用同一个类创建不同对象时,分别给与他们相同的初始化值。那么这两个对象的内容就是相同的。二是通过地址赋值来完成。即将第一个对象在内存中的地址赋值给第二个对象。此时两个对象名字虽然不同,但是他们却指向内存中的同一块区。此时就好像一个人有两个名字,其实是同一个人。所以这两个对象内容也就相同了。

  二、利用==运算符与equals方法来比较对象

  在Java语言中,主要可以利用==运算符(两个等号)equals函数来对对象进行比较。不过这两个符号其实现的机制不同。或者说,对于同样的两个对象,如果利用他们来进行比较的话,往往会有不同的结果。如StringJava自定义的对象,其主要用来存储字符串数据。现在笔者利用如下语句定义了三个String对象。


    String str1=new String(“welcome”); 

  String str2=new String(“welcome”); 
  String str3=str1; //创建一个对象,将对象str1的地址赋值给str3

  以上三个对象,显而易见,其内容都是相同的。但是利用这个两种方式来对他们进行比较的时候,往往会有不同的结果。如利用==(两个等号)比较符号来进行比较,str1==str2,最后返回的结构是false,也就是他们是不相同的对象。可是如果比较str1==str3对象,则最后返回的结果却是true。但是利用equal函数来比较,则返回的结果是相同的。为什么对象的内容相同,它们返回的结果却是不同的呢?

  要回答这个问题,就需要大家先回顾一下笔者上面谈到的几对关系。首先,对象str1与对象str2的关系,就好像是同一个模具出来的两个盒子,他们从外观看起来虽然相同,但是通过放大镜或者其他精密仪器仍然可以看到,两个盒子是不同的东西。这两个对象虽然内容相同,但是其在内存中分配的地址不同。也就是说,是同一个模具出来的外观看起来相同的不同的盒子。而对象str1与对象str3就好像是一个人有两个名字。虽然名字不同,但是实际上是同一个人。这主要是因为他们的身份证号码相同。其实这个身份证号码就好像是内存中分配的地址,而对象名字就好象是人的名字。一个人可以有好几个名字(一个对象有好几个名字),但是其身份证号码只有一个(内存分配地址只有一个)。在上面的语句中,通过str3=str1,其实现的功能,并不是将对象str1的值赋值给对象str3。而是将对象str1在内存中的地址赋值给了对象str3(就好像是将一个人的身份证号码复制给了另外一个人)。所以从本质上说,str3并不是一个新建立的对象。因为系统并没有在内存中为其分配一个新的存储区域(即并没有创造一个新的人),而只是好像给对象另外取了一个别名。

所以说,在对象比较的时候,需要搞清楚一个问题。即现在要比较的是他们的内容还是在内存中指向的地址。一般来说,内容相同不一定他们在内存中指向的地址也是相同的。而不同的对象在内存中若指向同一个地址,则他们的内容肯定是相同的(因为他们实际上就是同一个对象)。而==(两个等号)运算符与equals函数就是用来比较这两块内容的。其中==运算符是用来比较内存中的地址是否相同,即比较它们的身份证号码是否相同。而equals函数则只比较他们的内容,如果他们的内容相同,即使身份证号码不相同(内存中的地址不同),这个函数也会认为他们是相同的,会返回true值。这就是这两个对象比较方式的最大不同。或者说,他们在对对象进行比较时,出发点不同。一个比较对象名字所指向的内存地址是否相同,另外一个比较的是对象名字所指向的存储模块中的内容是否相同。所以他们就会返回不同的结果。 

三、慎用内存地址赋值

  在实际工作中,笔者提醒程序开发人员,要慎用这种str3=str1内存地址的赋值形式。其实,利用这种形式来创建对象,其实根本没有创建一个新的对象。而只是将两个对象同时指向内存中的同一个存储区域。由于他们实际上是同一个对象,为此通过其中一个对象修改了对象的内容,那么另外一个对象名字调用的对象其也会受到影响。也就是说,它们相互之间缺乏独立性。为此在创建对象的时候,如果没有特殊的必要,最好为不同的对象名创建不同的实体对象。而不要将多个对象名指向同一个对象,这在开发应用程序的时候容易导致对象内容被无意中修改,从而导致应用程序结果出错。

  最后笔者需要提醒的是,在选择对象比较方式的时候,要了解==运算符与equals函数之间的差异。如果只是想比较对象的内容是否相同,则只需要使用equals函数即可。但是如果要比较他们是否是同一个对象,即在内存中是否指向同一个存储区域,则需要使用==运算符。在实际应用的过程中,千万不能够张冠李戴。否则的话,很容易导致相反的结果。特别是将他们返回的值当作条件判断语句时,更加需要谨慎。因为此时如果选择的方法错误,则最后产生的结果往往是相反的。所以在对象进行比较时,跟变量的比较有很大的差异。在对象的比较上,程序员要谨慎行事。最根本的一点就是要搞清楚,到底比较的是什么东西,是对象内部的存储内容还是在对象名字与内存之间的关联关系(对象内存地址)。搞清楚这一点后,那么到底选择采用哪种方式来进行比较也就引刃而解了。

 

分享到:
评论

相关推荐

    ACCP 5.0 S2_使用JAVA实现面向对象编程

    本课程"ACCP 5.0 S2_使用JAVA实现面向对象编程"主要涵盖了以下几个关键知识点: 1. 类与对象:类是创建对象的蓝图,它定义了一组属性(数据成员)和方法(成员函数)。对象则是类的实例,具有类所定义的属性和行为...

    Java中对象与引用

    本文将从以下几个方面详细解析对象与引用的基本概念及其相互间的关系。 #### 一、对象与引用的基础概念 **对象**: 在Java中,对象是类的一个实例,即根据类的模板创建出来的具体实体。每个对象都有自己的属性(如...

    MyBatisDemo && JAVA把一个对象的全部属性复制到另一个相同的对象

    这篇博文“MyBatisDemo && JAVA把一个对象的全部属性复制到另一个相同的对象”探讨的是如何在Java编程中实现对象属性的深度复制。MyBatis是一个流行的Java持久层框架,它简化了数据库操作,而对象复制则是处理业务...

    Java对象池实现源码

    本篇文章将深入探讨Java对象池的实现原理,以及如何借鉴"Jakarta Commons Pool"组件来设计一个轻量级的对象池。 一、对象池的基本概念 对象池的基本工作流程包括以下几个步骤: 1. 初始化:预创建一定数量的对象并...

    java实例化对象的过程

    在Java编程语言中,实例化对象是创建类的实例,使其具有...总的来说,Java实例化对象是编程中的基本操作,它涉及到类的构造,内存分配,方法调用等多个核心概念。理解这一过程对于深入学习Java和面向对象编程至关重要。

    面向对象编程:C++与Java比较教程 英文版

    第15章讲述了扩展类的概念,这是面向对象编程中实现代码复用和模块化的重要方法。 第16章探讨了C++中的多重继承,这是一种高级特性,能够创建复杂的类层次结构,但同时也带来了复杂性。 第17章提供了一个面向对象...

    java实现http请求以及解析json与java对象转换 项目源代码实例

    具体到这个"java实现http请求以及解析json与java对象转换"项目,你可以期待以下几个关键知识点: 1. **HTTP请求**: - GET请求:获取服务器上的资源。 - POST请求:向服务器提交数据,常用于表单提交或API接口...

    Java语言中对象的理解与应用.pdf

    Java语言中对象的理解与应用包括以下几个方面: 1. 对象的定义:对象是Java语言中的基本单元,是程序设计的基本组成部分。 2. 对象的特征:对象具有某些特征,如属性和方法。 3. 对象的行为:对象的行为是对象的...

    java面向对象游戏

    在这个“java面向对象游戏”的项目中,我们看到开发者使用了Java OOP思想来实现一个猜拳游戏,这为初学者提供了一个很好的实践案例,帮助他们深入理解面向对象编程的概念。 面向对象编程的核心思想是将复杂的问题...

    Java多态和实现接口的类的对象赋值给接口引用的方法(推荐)

    Java的多态性是面向对象编程的一个核心特性,它允许我们使用父类(或接口)的引用指向子类(或实现接口的类)的对象。这样做的好处在于代码的灵活性和可扩展性,使得程序能够处理多种不同的对象类型,而不必关心具体...

    java中对象创建、初始化、引用

    在Java中创建一个对象通常涉及到以下几个步骤: - **声明引用**:首先需要声明一个引用变量,用于指向将来创建的对象。 - **创建对象**:使用`new`关键字创建对象,这会触发类的加载过程,并为对象分配内存空间。 -...

    ARIMA JAVA 实现

    1. 自回归(AR):AR部分假设当前值依赖于过去的几个值,即Y_t = c + φ1Y_{t-1} + φ2Y_{t-2} + ... + φpY_{t-p} + ε_t,其中c是常数,φi是自回归系数,p是自回归阶数,ε_t是误差项。 2. 整合(I):对于非...

    java 面向对象概念介绍

    在Java中,多态主要体现在以下几个方面: - **方法重载(Overloading)**:同一个类中的多个同名方法,但参数列表不同。例如: ```java public class Example { public void test() { // ... } public void ...

    java对象复制克隆

    在Java中实现深拷贝,我们可以有以下几种方法: 1. **实现Serializable接口**:这是通过序列化和反序列化实现深拷贝的方法。首先将对象转换为字节数组,然后从这个字节数组中反序列化出一个新的对象。这种方法简单...

    java面向对象课程设计(有程序和报告)

    Java面向对象课程设计是计算机科学领域中一个重要的实践环节,旨在帮助学生深入理解面向对象编程的概念和技巧。在这个课程设计中,学生通常会被要求完成一个实际的项目,使用Java语言来实现,同时需要提交详细的报告...

    java 中如何从LIST 对象取值

    Java标准库提供了几种实现`List`接口的类,如`ArrayList`、`LinkedList`和`Vector`等。其中,`ArrayList`是最常用的实现之一,它基于动态数组实现,提供随机访问元素的快速性能。 ### 二、从List中取值 #### 2.1 ...

    Java面向对象复习题目

    在Java中,当一个对象调用另一个对象的方法时,就发生了消息传递。这是对象间通信的主要方式。例如,一个Person对象可以向另一个Person对象发送消息(调用方法),如问候对方。消息传递的关键在于方法调用,它是Java...

    java类与对象教学(2)

    在“java类与对象教学(2)”中,我们将深入探讨几个关键知识点:对象重构、`this`关键字、静态变量与静态方法,以及对象的进一步讨论和包的使用。 1. **对象重构**: 重构是改进代码结构的过程,不改变其外部行为,...

    Java面向对象五子棋

    在五子棋游戏中,可能会有以下几个关键类: 1. **棋盘类(Board)**:用于存储游戏状态,包括棋盘大小、棋子位置等信息。它可能包含一个二维数组来表示棋盘格子,以及放置棋子、检查胜负、重置棋盘等方法。 2. **...

    java面向对象练习题-经典

    Java面向对象练习题是Java编程语言中非常重要的一部分,这些练习题涵盖了Java语言的基础知识,包括Java基本数据类型、运算符、控制结构、方法、类和对象、继承、多态、抽象类和接口等方面。通过这些练习题,可以对...

Global site tag (gtag.js) - Google Analytics