浅析java中String类型中“==”与“equal”的区别

一、前言

1.1、首先很多人都知道,String中用“==”比较的是地址,用equals比较的是内容,很多人对此用的是记忆法,通过记忆来加强此的引用,但是其真正的原理其实并不难,当我们真正明白其为什么的时候,用起来也会更加灵活,更加有底气(形容得不太好,朋友别见怪);

二相关知识的准备

  • 类型常量池
  • 运行时常量池
  • 字符串常量池

我们今天讨论的主题是当然是字符串常量池:
为什么在这要把另外两个常量池拿出说一下呢,首先小生我在网上或者cnds上看到很多人在争论字符串常量池是存在与方法区还是堆里面,因此我在这里面非常负责任的告诉各位读者:
1、类型常量池,存放在方法区里面,每个class文件都有一个
2、运行时常量池、存放在方法区里面,所有class共用
3、字符串常量池:存放在堆区里面
而且字符串常量池有一个特点:存放的常量唯一:三、 开始

3.1,情况一

public class Test2 {
	public static void main(String[] args) {

		String a ="张敬轩";
		String b ="张敬轩";

		System.out.println(a == b);
		System.out.println(a.equals(b));

	}
}

运行结果:

  • true
  • true

解释:因为当我们String a = “张敬轩”;的时候,会在堆里面的字符串常量池里面“搜索”是否有“张敬轩”这个对象,

  • 有:就会将“张敬轩这个对象的地址指向a”
  • 没有:就会在字符串常量池里面新建立一个“张敬轩”,然后就会把地址引用赋值给a

当再声明String b = “张敬轩";和第一次声明String = “张敬轩”;一样,先”搜索“,然后因为已经存在了”张敬轩“这个对象,那么就不会再创建对象,而是将存在的”张敬轩“的地址引用赋值给b,所以
a和b的地址一样,内容自然也一样,所以两个结果为true,不懂各位朋友懂没懂?

3.2,情况二;

public class Test2 {
	public static void main(String[] args) {

		String a ="张敬轩";

		String b = new String("张敬轩");

		System.out.println(a == b);
		System.out.println(a.equals(b));

	}
}

结果是

false,true
解释
String a = “张敬轩”;
已经解释过了,是在堆里面的字符串常量池创建对象
String b = new String(“张敬轩”);
这个也是在堆区里面创建对象,但是不是在字符串常量池里面创建对象
两个不同的对象,地址自然不同,类容都是张敬轩,所以结果是false,true

3.3、情况三

public class Test2 {
	public static void main(String[] args) {

		String a = new String("张敬轩");

		String b = new String("张敬轩");

		System.out.println(a == b);
		System.out.println(a.equals(b));

	}

}

结果:false,true

解释,因为new (“张敬轩”);表示在堆区的非字符串常量池里面创建了两个不同的对象,两次new就创建了两个,所以地址是不同的,因此结果是false,true

3.4、情况四

public class Test2 {
	public static void main(String[] args) {

		String a = "张"+"敬轩";
		String b = "张敬轩";
		System.out.println(a == b);
		System.out.println(a.equals(b));

	}
}

结果是:true,true

解释:String = “张敬” + ”轩“;
在编译的时候就已经开始进行计算:这是Java编译的优化机制,所以a指向的地址依旧是”张敬轩“;所以情况和前面的情况一一致,所以是true,true
(注意Java编译优化机制只针对常量不针对变量 a = a+ b(这个是没有优化机制的,关于Java编译机制,各位小伙伴可以去百度了解一下))

3.5、情况五

public class Test2 {
	public static void main(String[] args) {

		String a = "张";
		String b = "敬轩";
		String c =a+b;
		String d = "张敬轩";
		System.out.println(d == c);
		System.out.println(d.equals(c));

	}
}

结果:

解释:因为a 和 b是变量,不存在什么Java优化机制,而是将两个c = a + b存放在的是堆区的非字符常量池里面,所以是两个不同的对象,自然为false,true
3.6、最后一种情况

public class Test2 {
	public static void main(String[] args) {

		String a = "张";
		String b = "敬轩";
		String c =(a+b).intern();
		String d = "张敬轩";
		System.out.println(d == c);
		System.out.println(d.equals(c));

	}

}

结果:

解释:intern();方法是将堆区里面的非字符常量池里面的对象强行放到字符常量池里面,因为字符常量池里面对象的唯一性,如果字符串常量池里面已经有了和”张敬轩“一样的对象,就会将其地址引用赋值给c,没有就相当于创建一个(也就是和之前堆区里面那个对象一样的对象),有了的话,就会将原来有的那个“张敬轩”对象赋值给c,因为地址一样,所以为true

总结:

== 比较的地址 (如果对象存在字符串常量池,而且类容相同,那么 == 返回的是true )
equal 比较的是内容 (内容相同返回便是true)(所以在以后的开发中一般是用equal比较字符串的

各位朋友如果有错的及时评论区指出,谢谢大家的支持

到此这篇关于浅析java中String类型中“==”与“equal”的区别的文章就介绍到这了,更多相关java String类型 ==与equal内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • JAVA中string数据类型转换详解

    在JAVA中string是final类,提供字符串不可以修改,string类型在项目中经常使用,下面给大家介绍比较常用的string数据类型转换: String数据类型转换成long.int.double.float.boolean.char等七种数据类型 复制代码 代码如下: * 数据类型转换 * @author Administrator * */ public class 数据类型转换 { public static void main(String[] args) { String c=

  • 简单谈谈Java中String类型的参数传递问题

    提要:本文从实现原理的角度上阐述和剖析了:在Java语言中,以 String 作为类型的变量在作为方法参数时所表现出的"非对象"的特性. 一.最开始的示例 写代码最重要的就是实践,不经过反复试验而得出的说辞只能说是凭空遐想罢了.所以,在本文中首先以一个简单示例来抛出核心话题: public class StringAsParamOfMethodDemo { public static void main(String[] args) { StringAsParamOfMethodDem

  • java中equals和等号(==)的区别浅谈

    java中的数据类型,可分为两类:1.基本数据类型,也称原始数据类型.byte,short,char,int,long,float,double,boolean   他们之间的比较,应用双等号(==),比较的是他们的值. 2.复合数据类型(类)   当他们用(==)进行比较的时候,比较的是他们在内存中的存放地址,所以,除非是同一个new出来的对象,他们的比较后的结果为true,否则比较后结果为false.JAVA当中所有的类都是继承于Object这个基类的,在Object中的基类中定义了一个eq

  • Java中==符号与equals()的使用详解(测试两个变量是否相等)

    Java 程序中测试两个变量是否相等有两种方式:一种是利用 == 运算符,另一种是利用equals()方法. 当使用 == 来判断两个变量是否相等时,如果两个变量是基本类型变量,且都是数值类型(不一定要求数据类型严格相同),则只要两个变量的值相等,就返回true. 但是对于两个引用类型变量,只有它们指向同一个对象时, == 判断才会返回true. == 不可用于比较类型上没有父子关系的两个对象. 很多书上说equals()方法是判断两个对象的值相等.这种说法不准确.实际上equals()方法是O

  • java对象转换String类型的三种方法

    一.采用Object.toString()toString方法是java.lang.Object对象的一个public方法.在java中任何对象都会继承Object对象,所以一般来说任何对象都可以调用toString这个方法.这是采用该种方法时,常派生类会覆盖Object里的toString()方法.但是在使用该方法时要注意,必须保证Object不是null值,否则将抛出NullPointerException异常. 二.采用(String)Object 该方法是一个标准的类型转换的方法,可以将

  • 基于Java字符串 "==" 与 "equals" 的深入理解

    虽然关于Java字符串"=="和"equals"的问题是Java学习中的最基础的一个问题,但是仍然有不少刚刚学习Java的同学搞不清楚里面的原理,最近和朋友讨论到这个问题,所以写篇文章给大家分享一下我自己的理解.首先让我们看一个例子: 复制代码 代码如下: public class TestStringEquals { public static void main(String[] args) { String a = "test";     

  • java String 类的一些理解 关于==、equals、null

    1.String 的==与equal() 在对字符串的相等判断,==判断的是地址是否相同,equal()判断的是字符值是否相同.大多数时候==跟equal()的结果都是相同的.这是因为String对象是不变模式的,如果你不是明确地new一个String对象,Java对于String对象的保存默认的是会把新生成的String 对象放到一个缓冲区,然后每次判断缓冲区中是否已经有了这个对象,如果有了,那么后建立的同样字符值的String对象也会指向最初建立是该字符值对象的地址.也就是说字符值相同的时候

  • Java中char数组(字符数组)与字符串String类型的转换方法

    本文实例讲述了Java中char数组(字符数组)与字符串String类型的转换方法.分享给大家供大家参考,具体如下: 在Java语言编程时,使用"口令字段"jPasswordField组件时,如果要获得密码值,就需要使用该组件的getPassword()方法.jPasswordField的getPassword()方法返回一个char类型的数组,我们经常需要将这个数组转换为String类型,以便进行诸如口令匹配或口令赋值等操作.这时,就需要将char类型的数组进行转换.当然也经常会遇到

  • 浅析java中String类型中“==”与“equal”的区别

    一.前言 1.1.首先很多人都知道,String中用"=="比较的是地址,用equals比较的是内容,很多人对此用的是记忆法,通过记忆来加强此的引用,但是其真正的原理其实并不难,当我们真正明白其为什么的时候,用起来也会更加灵活,更加有底气(形容得不太好,朋友别见怪): 二相关知识的准备 类型常量池 运行时常量池 字符串常量池 我们今天讨论的主题是当然是字符串常量池: 为什么在这要把另外两个常量池拿出说一下呢,首先小生我在网上或者cnds上看到很多人在争论字符串常量池是存在与方法区还是堆

  • 详解Java中String类型与默认字符编码

    为什么写这个 至于为什么要写这个,主要是一句mmp一定要讲,绕了一上午,晕死 Java程序中的中文乱码问题一直是一个困扰程序员的难题,自己也不例外,早在做项目时就遇到过很多编码方式的坑,当时想填来着,但是嫌麻烦.这次终于忍不住了,一定要弄个明白 String类型的编码方式 从网上查的资料都说,Java默认的字符编码是Unicode,而String类型的编码方式是与JVM编码方式和本机操作系统默认字符集有关的.于是我做出了测试 在Java中可以这样显示查看本地编码方式(JVM还是OS呢?) //

  • java 中String和StringBuffer与StringBuilder的区别及使用方法

    java 中String和StringBuffer与StringBuilder的区别及使用方法 1. String 类 String的值是不可变的,这就导致每次对String的操作都会生成新的String对象,不仅效率低下,而且大量浪费有限的内存空间. String a = "a"; //假设a指向地址0x0001 a = "b";//重新赋值后a指向地址0x0002,但0x0001地址中保存的"a"依旧存在,但已经不再是a所指向的,a 已经指向

  • 深入剖析java中String、StringBuffer、StringBuilder的区别

    java中String.StringBuffer.StringBuilder是编程中经常使用的字符串类,他们之间的区别也是经常在面试中会问到的问题.现在总结一下,看看他们的不同与相同. 1. 可变与不可变 String类中使用字符数组保存字符串,如下就是,因为有"final"修饰符,所以可以知道string对象是不可变的. private final char value[]; StringBuilder与StringBuffer都继承自AbstractStringBuilder类,在

  • 详解java中String、StringBuilder、StringBuffer的区别

    你知道String.StringBuilder.Stringbuffer的区别吗?当你创建字符串的时候,有考虑过该使用哪个吗? 别急,这篇文章带你解决这些问题. 可变性 首先,String是字符串,我们一般这样声明: String s = "abc"; String类使用被final修饰的char数组来存储字符串的内容,它的一大特性就是不可变,怎么理解这个不可变呢? 我们知道,一个类被final修饰,那么这个类无法被继承,方法也不能被重写,属性也不能改变. 看看这段代码: String

  • java中String、StringBuffer与StringBuilder的区别

    String String类是不可变类,即一旦一个String对象被创建以后,包含在这个对象中的字符序列是不可改变的,直至这个对象被销毁. 这个是String类的解释,之前小咸儿看到这个情况,不能理解上述的解释,如下 String a = "123"; a = "456"; // 打印出来的a为456 System.out.println(a) 看到这里,小咸儿不明白了,这不是明明已经对他进行修改了吗?为什么还说他是一个不可变类呢? 经过小咸儿和小伙伴们的学习,明白

  • c#中String类型的存储原理详解

    在我们正式了解c#中的String类型前,先来判断一下下面代码的结果吧~ String str1 = "123"; String str2 = str1; str2 = "321"; Console.WriteLine(str1); 上面代码的最终输出结果是123,如果有浅学过引用类型的同学一定会问:str2不是在存储的是str1的引用么?那么str2不是和str1指向堆中同一块内存空间么?为什么在引用了str2使其改变数据后再打印出str1最终还是打印出来123?

  • Java中将String类型依照某个字符分割成数组的方法

    将下列字符串,依照|拆分成数组: String numbers = "1|2|3|4|5"; 使用split拆分 String[] numberArray = numbers.split("\\| "); 以上这篇Java中将String类型依照某个字符分割成数组的方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们. 您可能感兴趣的文章: java 字符串分割的三种方法(总结) Java中分割字符串的两种方法实例详解 java Stri

  • java判断String类型是否能转换为int的方法

    使用正则表达式,效率较高 public boolean canParseInt(String str){ if(str == null){ //验证是否为空 return false; } return str.matches("\\d+"); //使用正则表达式判断该字符串是否为数字,第一个\是转义符,\d+表示匹配1个或 //多个连续数字,"+"和"*"类似,"*"表示0个或多个 } 以上这篇java判断String类型是

  • Java之String、StringBuffer、StringBuilder的区别分析

    相信大家对 String 和 StringBuffer 的区别也已经很了解了,但是估计还是会有很多同志对这两个类的工作原理有些不清楚的地方,今天我在这里重新把这个概念给大家复习一下,顺便牵出 J2SE 5.0 里面带来的一个新的字符操作的类-- StringBuilder .那么这个 StringBuilder 和 StringBuffer 以及我们最早遇见的 String 类有那些区别呢?在不同的场合下我们应该用哪个呢?我讲讲自己对这几个类的一点看法,也希望大家提出意见,每个人都有错的地方,在

随机推荐