Java中String类型具有一个equals的方法能够用于推断两种字符串是否相等,可是这样的相等又与运算符==所推断的“相等”有所不同,接下来进行分析,结论由程序进行验证

String的equals函数仅仅要两个字符串“看起来”相等,就能够返回true,“看起来”相等意思指的是,当两个字符串对象所存放的内容同样时,不须要存放的内存地址同样,可是==推断则仅仅有当推断的两个变量所使用的内存地址为同样时才返回true。比如有两个长得一模一样的双胞胎A,B,若使用A==B来推断会返回false。使用A.equals(B)则会返回true。

我们能够看object中的equals函数的源代码为

public boolean equals(Object obj) {
return (this == obj);
}

我们知道Java中全部的对象都默认继承自Object类。所以当我们没有重写equals的方法时,若使用equals来推断两个对象的是否相等时。仅仅有这两个对象指向的是同一个内存地址时。才会返回true,否则即使内容全然同样但在内存中是两个不同的内存地址也是返回false,此时若用双胞胎A,B来对照。A==B与A.equals(B)返回的都是false。

既然如此,那String的equals与==为什么会不一样呢,这里我们要看一下String中重写equals的源代码:

public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String) anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}

能够看出String中的equals函数首先推断其内存地址是否为同一个:

 if (this == anObject) {
return true;
}

然后再推断其内容是否同样:

if (anObject instanceof String) {
String anotherString = (String) anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}

当我们使用字符串连接--连接方式一般为+或concat("substring")--的方式创建字符串时,都会构建一个新的String对象。即在内存中开辟一个新的地址来存放,所以这个时候即使内容同样。用==推断的话,也是返回false;当我们使用等号赋值时,若内存中有该字符串。则该变量指向此内存地址二不是又一次创建一个,所以此时用==时会返回true,我们看一下例程:

public class StringTest01 {

	public static void main(String[] args) {
// TODO Auto-generated method stub String hello="hello";
String hel1=hello;
String hel2="hel";
String hel3=hel2+"lo";
String hel4=hel2.concat("lo"); System.out.println(hello);
System.out.println(hel1);
System.out.println(hel3);
System.out.println(hel4);
//==等号測试
System.out.println(hello==hel1);
System.out.println(hello==hel3);
System.out.println(hello==hel4);
System.out.println(hel3==hel4); //equals函数測试
System.out.println(hello.equals(hel1));
System.out.println(hello.equals(hel3));
System.out.println(hello.equals(hel4));
System.out.println(hel3.equals(hel4)); //StringBuilder測试
StringBuilder helloBuilder = new StringBuilder("hel");
System.out.println(helloBuilder.equals(hel2));
} }

其输出结果为:

最后一个StringBuilder的測试我们发现尽管使用equals来推断,可是返回的是false。这是为什么呢?

首先。当我们使用StringBuilder创建对象时。肯定会在内存中开辟一个新的专属的地址用于存放对象内容。可是即使StringBuilder中存放的内容与其它字符串的内容同样,使用equals来推断也是返回false,这是由于StringBuilder并没有重写equals函数。即StringBuilder的equals为:

public boolean equals(Object obj) {
return (this == obj);
}

所以会返回false。

Java中String推断相等equals与==的差别以及StringBuilder的equals的更多相关文章

  1. Java中string 创建对象时 “”和null的差别

    null和""的差别 问题一: null和""的差别 String s=null; string.trim()就会抛出为空的exception String s ...

  2. 关于==和equals()方法&Java中string与char如何转换&String,StringBuffer

    1.对于基本数据类型,可以直接使用==和!=进行内容比较 如:int x=30;        int y=30;         x==y;  //true 基本数据类型 简单类型(基本类型) bo ...

  3. 【转载】 Java中String类型的两种创建方式

    本文转载自 https://www.cnblogs.com/fguozhu/articles/2661055.html Java中String是一个特殊的包装类数据有两种创建形式: String s ...

  4. Java中String类的特殊性

    java中特殊的String类型 Java中String是一个特殊的包装类数据有两种创建形式: String s = "abc"; String s = new String(&q ...

  5. java中string内存的相关知识点

    (一):区别java内存中堆和栈: 1.栈:数据可以共享,存放基本数据类型和对象的引用,其中对象存放在堆中,对象的引用存放在栈中: 当在一段代码块定义一个变量时,就在栈中 为这个变量分配内存空间,当该 ...

  6. java中String的相等比较

    首先贴出测试用例: package test; import org.junit.Test; /** * Created by Administrator on 2015/9/16. * */ pub ...

  7. Java中String类的方法及说明

    String : 字符串类型 一.      String sc_sub = new String(c,3,2);    //      String sb_copy = new String(sb) ...

  8. java中String类型变量的赋值问题

    第一节 String类型的方法参数 运行下面这段代码,其结果是什么? package com.test; public class Example { String str = new String( ...

  9. java中String的常用方法

    java中String的常用方法1.length() 字符串的长度 例:char chars[]={'a','b'.'c'}; String s=new String(chars); int len= ...

随机推荐

  1. Day4上午解题报告

    预计分数:50 +0+0=50 实际分数:50+0+10=60 毒瘤出题人,T3不给暴力分 (*  ̄︿ ̄) T1 https://www.luogu.org/problem/show?pid=T155 ...

  2. HDU 多校联合 6033 6043

    http://acm.hdu.edu.cn/showproblem.php?pid=6033 Add More Zero Time Limit: 2000/1000 MS (Java/Others)  ...

  3. 关于Webpack详述系列文章 (第一篇)

    WebPack官网地址(https://webpack-china.org/) 1. 什么是WebPack WebPack可以看做是模块打包机:它做的事情是,分析你的项目结构,找到JavaScript ...

  4. Servlet 规范笔记—基于http协议的servlet

    在上一章节,我们大概的描述了servlet的规范以及servlet和servlet容器的概念和用途,我们清楚的知道servlet容器提供了接收来自client端的请求,然后根据请求进行处理(如:执行对 ...

  5. 使用JOTM实现分布式事务管理(多数据源)

    使用spring和hibernate可以很方便的实现一个数据源的事务管理,但是如果需要同时对多个数据源进行事务控制,并且不想使用重量级容器提供的机制的话,可以使用JOTM达到目的. JOTM的配置十分 ...

  6. jquery ui 分页插件 传入后台的连个參数名

    參数名: page .rows page=int(request.form.get('page',1).encode('u8')) rows1=int(request.form.get('rows', ...

  7. Java exception handling best practices--转载

    原文地址:http://howtodoinjava.com/2013/04/04/java-exception-handling-best-practices/ This post is anothe ...

  8. 2 Java基础语法(keyword,标识符,凝视,常量,进制转换,变量,数据类型,数据类型转换)

    1:keyword(掌握) (1)被Java语言赋予特定含义的单词 (2)特点: 所有小写. (3)注意事项: A:goto和const作为保留字存在. B:类似于Notepad++这种高级记事本会对 ...

  9. jquery的滚动事件

    $(selector).scroll(function);当滚动到合适的条件下,就触发某个函数. 现在基本就是前端利用AJAX对数据进行拼接操作,渲染进html的DOM结构中.

  10. call.apply.冒充对象继承

    call方法:让调用对象执行,然后第一参数是谁.调用对象的this就改变,指向谁,后边跟参数,依次对应传入 apply方法:让调用对象执行,然后第一参数是谁.调用对象的this就改变指向是谁,后边跟参 ...