我们先看代码

String str1 = new String("hello");
String str2 = "hello"; System.out.println("str1==str2: " + (str1==str2)); \\1
System.out.println("str1.equals(str2): " + str1.equals(str2)); \\2

输出结果:

str1==str2: false
str1.equals(str2): true

关于==和equals,我们需要知道java中的数据类型,可分为两类:

1.基本数据类型,也称原始数据类型。byte,short,char,int,long,float,double,boolean
他们之间的比较,应用双等号(==),比较的是他们的值。
2.复合数据类型(类)
当他们用(==)进行比较的时候,比较的是他们在内存中的存放地址,所以,除非是同一个new出来的对象,他们的比较后的结果为true,否则比较后结果为false。 JAVA当中所有的类都是继承于Object这个基类的,在Object中的基类中定义了一个equals的方法,这个方法的初始行为是比较对象的内存地 址,但在一些类库当中这个方法被覆盖掉了,如String,Integer,Date在这些类当中equals有其自身的实现,而不再是比较类在堆内存中的存放地址了。
对于复合数据类型之间进行equals比较,在没有覆写equals方法的情况下,他们之间的比较还是基于他们在内存中的存放位置的地址值的,因为Object的equals方法也是用双等号(==)进行比较的,所以比较后的结果跟双等号(==)的结果相同。

  因为string属于符合数据类型,所以应该是使用equals,假如我们使用==比较,肯定是比较它们的内存地址了,所以\\1 \\2 的结果显而易见了

  要想判断两个对象是否相等,不能通过比较两个对象的引用是否相等,这是永远都得不到相等的结果的,因为两个对象的引用永远不会相等,所以正确的比较方法是直接比较这两个对象,比较这两个对象的实质是不是一样的,即这两个对象里面的内容是不是相同的,通过比较这两个对象的属性值是否相同而决定这两个对象是否相等。

  Object类提供了一个equals()方法来比较两个对象的内容是否相同,因此我们可以采用这个方法去比较两个对象是否在逻辑上“相等”。如:c1.equals(c2);这里是调用从Object类继承下来的equals()方法,通过查阅API文档得到Object类里的equals方法的定义如下:

public boolean equals(Object obj)

注意,在重写equals方法时,需要按照以下几个规则设计:

1自反性 :对任意引用值X,x.equals(x)的返回值一定为true.
2对称性: 对于任何引用值x,y,当且仅当y.equals(x)返回值为true时,x.equals(y)的返回值一定为true;
3传递性:如果x.equals(y)=true, y.equals(z)=true,则x.equals(z)=true
4一致性:如果参与比较的对象没任何改变,则对象比较的结果也不应该有任何改变
5非空性:任何非空的引用值X,x.equals(null)的返回值一定为false

再看代码:

String str2 = "hello";
String str3 = "hello";
System.out.println("str3==str2: " + (str3==str2)); \\3
System.out.println("str3.equals(str2): " + str3.equals(str2)); \\4

  

输出结果:

str3==str2: true
str3.equals(str2): true

这里的又为什么都是输出true呢,因为它们都是从缓冲池取出来的,由于string类比较特殊,jdk专门做了缓存优化。

  原来Java运行时会维护一个String Pool(String池)。String池用来存放运行时中产生的各种字符串,并且池中的字符串的内容不重复。而一般对象不存在这个缓冲池,并且创建的对象仅仅存在于方法的堆栈区。
也就是说需要看string创建的方式:

1 当使用任何方式来创建一个字符串对象s时,Java运行时(运行中JVM)会拿着这个X在String池中找是否存在内容相同的字符串对象,如果不存在,则在池中创建一个字符串s,否则,不在池中添加。
2 Java中,只要使用new关键字来创建对象,则一定会(在堆区或栈区)创建一个新的对象。
3 使用直接指定或者使用纯字符串串联来创建String对象,则仅仅会检查维护String池中的字符串,池中没有就在池中创建一个,有则罢了!但绝不会在堆栈区再去创建该String对象。
4 使用包含变量的表达式来创建String对象,则不仅会检查维护String池,而且还会在堆栈区创建一个String对象。

  另外,String的intern()方法是一个本地方法,定义为public native String intern(); intern()方法的价值在于让开发者能将注意力集中到String池上。当调用 intern 方法时,如果池已经包含一个等于此 String 对象的字符串(该对象由 equals(Object) 方法确定),则返回池中的字符串。否则,将此 String 对象添加到池中,并且返回此 String 对象的引用。

java之从字符串比较到==和equals方法区别的更多相关文章

  1. java数组、java.lang.String、java.util.Arrays、java.lang.Object的toString()方法和equals()方法详解

    public class Test { public static void main(String[] args) { int[] a = {1, 2, 4, 6}; int[] b = a; in ...

  2. (转载)java中判断字符串是否为数字的方法的几种方法

    java中判断字符串是否为数字的方法: 1.用JAVA自带的函数 public static boolean isNumeric(String str){ for (int i = 0; i < ...

  3. Java中字符串比较时==和equals的区别

    ==是比较两个字符串引用的地址是否相同,即是否指向同一个对象,而equals方法则比较字符串的内容是否相同. 例如String a = "abc"; String b = &quo ...

  4. java如何判断字符串是否为空的方法

    以下是java 判断字符串是否为空的四种方法: 方法一: 最多人使用的一个方法, 直观, 方便, 但效率很低: if(s == null ||"".equals(s)); 方法二: ...

  5. JAVA中“==”与equals()方法区别

    equals 方法是 java.lang.Object 类的方法 有两种用法说明: ()对于字符串变量来说,使用"=="和"equals()"方法比较字符串时, ...

  6. JAVA学习(二) String使用equals方法和==分别比较的是什么?(转)

    String使用的equals方法和==的区别 equals方法和==的区别   首先大家知道,String既可以作为一个对象来使用,又可以作为一个基本类型来使用.这里指的作为一个基本类型来使用只是指 ...

  7. Java基础学习总结(1)——equals方法

    一.equals方法介绍 1.1.通过下面的例子掌握equals的用法 package cn.galc.test; public class TestEquals { public static vo ...

  8. 字符串--java中判断字符串是否为数字的方法的几种方法?

    ava中判断字符串是否为数字的方法: 1.用JAVA自带的函数 public static boolean isNumeric(String str){ for (int i = 0; i < ...

  9. java中判断字符串是否为数字的方法的几种方法

    1.用JAVA自带的函数 public static boolean isNumeric(String str){ for (int i = 0; i < str.length(); i++){ ...

随机推荐

  1. 【Java基础】单例模式

    单例模式:保证整个项目运作期间某一个对象有且只有一个. 主要有:1,饿汉式:2,懒汉式. class Singleton1//饿汉式 { private Singleton1(){}//先把构造方法私 ...

  2. log4.net 日志工具使用

    1. 在应用程序的相同目录下建立: winform :    程序名.exe.config          .(log4net程序,就log4net.exe.config) web:         ...

  3. Illustrated C#学习笔记(一)

    迄今为止最容易看懂的一本C#入门图书,的确是,很不错的一本书,继续读下去,并做好相关笔记吧. Chapter 1 C#和.NET框架 主要讲述了一些.NET框架下的一些不明觉厉的名词如CLR,CLI. ...

  4. 数据库学习之ADO.NET五大对象

    1 [ADO.NET]      ado.net 是一种数据访问技术,使得应用程序能够连接到数据存储,并以各种方式操作存储在里面的数据.    2 [ADO.NET五大常用对象]     Connec ...

  5. Win7窗口操作

    1.使用 Aero Shake 晃动最小化打开的窗口您可以使用 Aero Shake 晃动将所有打开的窗口快速最小化,只剩下您需要使用的窗口.然后,还可以轻松还原所有窗口.操作方法如下:1. 在需要保 ...

  6. SQL Server T-SQL基础

    --数据库:数据库软件:mssqlserver,oracle,db2, ACCESS,SQLITE --数据库文件:分数据文件(MDF)和日志文件(log) 班级名称:(四期班训练营)长度可变,有中文 ...

  7. final的深入理解 - final数据

    先通过例子看一看: package com.sotaof.testfinal; public class Value { int i; public Value(int i){ this.i = i; ...

  8. SQLServer 2012 可视化窗口中,设置“时间”默认值为“当前时间"

    最近,需要在SQLServer 2012中,设置datetime的默认值为当前时间. 通过可视化窗口进行设置,而不是将getdate()函数写在sql语句中,也不是将‘2022-2-2 22:22:2 ...

  9. PHP记录点击数方法

    1.第一种方法: $id = $_GET['id']; //获取文章ID $sql = "UPDATE base SET hits = hits+1 WHERE id = '$id'&quo ...

  10. API例子:用Python驱动Firefox采集网页数据

    1,引言 本文讲解怎样用Python驱动Firefox浏览器写一个简易的网页数据采集器.开源Python即时网络爬虫项目将与Scrapy(基于twisted的异步网络框架)集成,所以本例将使用Scra ...