java String类常量池分析及"equals"和"==”区别详细介绍
作者:lqh 发布时间:2021-11-28 01:54:48
java "equals"和"==”异同
首先简单说一下“equal”和“==”
==操作对于基本数据类型比较的是两个变量的值是否相等,
对于引用型变量表示的是两个变量在堆中存储的地址是否相同,
即栈中的内容是否相同
equals操作表示的两个变量是否是对同一个对象的引用,
即堆中的内容是否相同。
综上,==比较的是2个对象的地址,而equals比较的是2个对象的内容。
再简单介绍一下String类
String类 又称作不可变字符序列
String使用private final char value[]来实现字符串的存储,也就是说String对象创建之后,就不能再修改此对象中存储的字符串内容。String类有一个特殊的创建方法,就是使用""双引号来创建。例如new String("123")实际创建了2个String对象,一个是"123"通过""双引号创建的,另一个是通过new创建的.只不过他们创建的时期不同,一个是编译期,一个是运行期。java对String类型重载了+操作符,可以直接使用+对两个字符串进行连接。运行期调用String类的intern()方法可以向String Pool中动态添加对象。
区分两种创建String对象的方法“”和new()
String是一个特殊的包装类数据。可以用:
String str1 = new String("123");
String str2 = "123";
两种的形式来创建
第一种是用new()来新建对象的,它会在存放于堆中。每调用一次就会创建一个新的对象。(实际是两个正如上文所说,但是在常量池中存在“123”后就不会再在常量池中创建新的“123”)
第二种是先在栈中创建一个对String类的对象引用变量str,然后通过符号引用去字符串常量池里找有没有"abc",如果没有,则将"abc"存放进字符串常量池,并令str指向”abc”,如果已经有”abc”则直接令str指向“abc”。
这时我们应该注意
一方面,第一种写法有利与节省内存空间.同时它可以在一定程度上提高程序的运行速度,因为JVM会自动根据栈中数据的实际情况来决定是否有必要创建新对象。而对于String str = new String("123");的代码,则一概在堆中创建新对象,而不管其字符串值是否相等,是否有必要创建新对象,从而加重了程序的负担。另一方面,我们在使用诸如String str = "123";的格式定义类时,总是想当然地认为,创建了String类的对象str。
对象可能并没有被创建!而可能只是指向一个先前已经创建的对象。只有通过new()方法才能保证每次都创建一个新的对象。
请看下列实例
package testString;
public class testString
{
public static void main(String[] args)
{
String a = "123";
String b = "123";
System.out.println(a==b);
System.out.println(a.equals(b));
System.out.println("------------------------------------------");
/**
* true
* true
* 此处创建一个字符串"123"储存在常量池中
* 因为"123"储存在常量区,并且唯一,即两个String引用a和b所的地址相同所以a==b为true
* 并且两个引用在所指对象在堆中的内容相同所以a.equals(b)为true
*/
String c = new String("1234");
String d = new String("1234");
System.out.println(c==d);
System.out.println(c.equals(d));
System.out.println("------------------------------------------");
/*
* false
* true
* 此处创建三个字符串“1234”,一个在常量池中,两个通过new储存在堆中
* 因为c和d此时指向的是堆中的两个String对象,所以地址不同 c==d为false
* 但是c与d堆中内容相同所以c.equals(d)为true
*/
String e = "a1";
String f = "a"+1;
System.out.println(e==f);
System.out.println(e.equals(f));
System.out.println("------------------------------------------");
/**
* true
* true
* 此处创建“a1”“a”2个字符串其中“a1”“a”他们两个均在常量池中,你可能会问+是个运算符重载么?
* 是的,java自己有一定的运算符重载但是你没法使用定义自己的运算符重载,和c++不同,String f = "a"+1;
* 这句会被编译器做成 String f=“a1”;这与我们讲到的第一种情况相同,不再赘述。
* 编译器之所以这么做是因为他在编译时就能够确定
*/
String g = "gh";
String hh = "h";
String h = "g" + hh ;
System.out.println(g==h);
System.out.println(g.equals(h));
System.out.println("------------------------------------------");
/**
* false
* true
* 与上面不同的是这里的h在编译时不能确定(编译器是这样认为的),所以h所指的对象在运行时确定储存在堆中,
* 所以g==h为true而g.equals(h)为false
*/
}
}
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
来源:http://blog.csdn.net/qq_22841811/article/details/46317969


猜你喜欢
- 1 简介之前我们在文章《K8ssandra入门-详细记录在Linux上部署K8ssandra到Kubernetes》成功地在Ubuntu上安
- Spring开启注解AOP的支持放置的位置放在springmvc的aop,需要在springmvc的配置文件中写开启aop,而不是sprin
- 本文实例讲述了C#实现的算24点游戏算法。分享给大家供大家参考。具体如下:using System;using System.Collect
- springcloud-gateway集成knife4j环境信息环境信息spring-boot:2.6.3spring-cloud-alib
- 前言springboot提供了 spirng-boot-starter-test 以供开发者使用单元测试,在引入 spring-boot-s
- 接收JSON浏览器传来的参数,可以是 key/value 形式的,也可以是一个 JSON 字符串。在 Jsp/Servlet 中,我们接收
- JNDI的理解JNDI是 Java 命名与文件夹接口(Java Naming and Directory Interface),在J2EE规
- 这里的万年历制作主要用到了Calendar类和GregorianCalendar类,我们先来回顾一下基础知识:基础部分一、Cal
- 1.介绍在SpringBoot的Web项目中,默认采用的是内置Tomcat,当然也可以配置支持内置的jetty,内置有什么好处呢? 1. 方
- MyBatis多数据源配置(读写分离)首先说明,本文的配置使用的最直接的方式,实际用起来可能会很麻烦。实际应用中可能存在多种结合的情况,你可
- 1 概述Java虚拟机把描述类的数据从Class文件加载到内存, 并对数据进行校验、转化解析和初始化,最终形成可以被虚拟机直接使用的Java
- 前言之前我们提到了 CustomPaint er 的 Paint 可以使用渐变(GradientShader)来填充绘制的图形,本篇我们来介
- 本文实例为大家分享了Flutter实现底部导航栏的具体代码,供大家参考,具体内容如下效果实现先将自动生成的main.dart里面的代码删除,
- 在Servlet2.5中,我们要实现文件上传功能时,一般都需要借助第三方开源组件,例如Apache的commons-fileupload组件
- 文章来源:aspcn 作者:孙雯服务器Sockets列表9.2是一个服务器应用程序的一部分.列表9.2 一个简单的服务器程序 /** &n
- 新建类Product:class Product{ public string name; &
- .NET Framework为动态列表List提供泛型类List<T>。这个类实现了IList,ICollection,IEnu
- 一、介绍在实际的软件项目开发过程中,我可以很负责任的跟大家说,如果你真的实际写代码的时间超过5年,你对增删改查这类简单的功能需求开发,可以说
- 研究背景 我們在搞新的配置中心Nacos的時候,为了获取新的配置中心的配置文件中配置的 dat
- 一、什么是Activity?简单的说:Activity就是布满整个窗口或者悬浮于其他窗口上的交互界面。在一个应用程序中通常由多个Activi