Java基础之String中equals,声明方式,等大总结
无论你是一个编程新手还是老手,提到String你肯定感觉特别熟悉,因为String类我们在学习java基础的时候就已经学过,但是String类型有我们想象的那么简单吗?其实不然,String类型的知识点还是比较多的。今天就和大家来一起讨论一下,关于String的一些容易让人疑惑的地方,废话不多说进入正题。。。如有谬误请批评指正,如果有疑问请留言。我会在第一时间修改或回答
通过本篇博客你将学到以下知识
①==和equals的区别,String a="abc"和String a=new String("abc")的堆内存和栈内存的变化
②String a="abc"和String a=new String("abc")两种声明方式的区别
④String对象的值是不能修改的,为啥可以重新赋值,并且改变
⑤String a;和String a = null,String a =""的区别
- public class StringDemo {
- public static void main(String[] args) {
- String str1 = "hello";
- String str2 = new String("hello");
- String str3 = str2;
- System.out.println("str1==str2:"+(str1==str2));
- System.out.println("str1==str2:"+(str1==str3));
- System.out.println("str1==str2:"+(str2==str3));
- }
- }
打印结果如下
- public class StringDemo {
- public static void main(String[] args) {
- String str1 = "hello";
- String str2 = new String("hello");
- String str3 = str2;
- System.out.println("str1 equals str2:"+(str1.equals(str2)));
- System.out.println("str1 equals str2:"+(str1.equals(str3)));
- System.out.println("str1 equals str2:"+(str2.equals(str3)));
- }
- }
因为equals方法的作用是将内容进行比较,所以此处的返回结果都为true。
str1="hello";实际上就是把一个在堆内存中开辟好的堆内存空间的使用权给了str1对象,而使用这种方法还有另外一个好处,就是如果一个字符串已经被一个名称所引用,则以后再有相同的字符串声明时,就不会再重新开辟空间,而继续使用已经开辟好的堆内存,啥意思?我们通过一个例子来进行说明,这个例子的代码如下
- public class StringDemo {
- public static void main(String[] args) {
- String str1 = "hello";
- String str2 = "hello";
- String str3 = "hello";
- System.out.println("str1==str2:" + (str1 == str2));
- System.out.println("str1==str3:" + (str1 == str3));
- System.out.println("str2==str3:" + (str2 == str3));
- }
- }
咦,这是啥子情况啊?上面我们刚得出结论"=="在String中比较的是地址值,为什么打印结果都是true呢?其实这是java中一种共享设计,这种设计思路是,在java中形成一个对象池,在这个池中保存多个对象,新实例化的对象如果已经在池中定义了则不再重新定义,而从池中取出继续使用。String采用了这种设计,在Java运行环境中有一个字符串池,由String类维护。执行语句String str1="hello"时,首先查看字符串池中是否存在字符串"hello",如果存在则直接将"hello"赋给str1,如果不存在则先在字符串池中新建一个字符串"hello",然后再将其赋给str1。执行语句String str=new String("hello")时,不管字符串池中是否存在字符串"hello",直接新建一个字符串"hello"(注意:新建的字符串"hello"不是在字符串池中),然后将其付给str。前一语句的效率高,后一语句的效率低,因为新建字符串占用内存空间。String str = new String()创建了一个空字符串,与String
str=new String("")相同。
- public class StringDemo {
- public static void main(String[] args) {
- String str="hello";
- str=str+" world!";
- System.out.println("str="+str);
- }
- }
打印结果
- public class StringDemo {
- public static void main(String[] args) {
- String str1 = "hello";
- String str2 = null;
- System.out.println(str1.equals(str2));
- }
- }
- public class StringDemo {
- public static void main(String[] args) {
- String str1 = "hello";
- String str2 = null;
- System.out.println(str2.equals(str1));
- }
- }
和上面的代码唯一不同的是上面是str1.equals(str2),这里是str2.equals(str1),我们看看打印结果会是啥样。
- /**
- * Compares this string to the specified object. The result is {@code
- * true} if and only if the argument is not {@code null} and is a {@code
- * String} object that represents the same sequence of characters as this
- * object.
- *
- * @param anObject
- * The object to compare this {@code String} against
- *
- * @return {@code true} if the given object represents a {@code String}
- * equivalent to this string, {@code false} otherwise
- *
- * @see #compareTo(String)
- * @see #equalsIgnoreCase(String)
- */
- public boolean equals(Object anObject) {
- //判断是否是和自己比较
- if (this == anObject) {
- return true;
- }
- //判断传过来的anObject是否是String类型的实例
- 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;
- }
str2=null,此时str2并不是String类型的实例,不信你可以去验证,因为String str2=null,申明一个String类型的str2,同时在内存里申请了一个地址,但是该地址不指向任何引用地址,所以在执行这个判断时直接跳出if语句返回false。所以就不会报空指针啦啦啦。。。
String a = null ;申明一个string类型的 a,同时在内存里申请了一个地址,但是该地址不指向任何引用地址;
String a = "" ;申明一个string类型的 a,既在内存里申请了地址,该地址又指向一个引用该字符串的引用地址;
string a=null,String b="hello"; system.out.println(a+b);输出nullhello;
s1=new String("s1")时创建了两个对象,而接着执行String s2=new String("s1")时,("s1")也会被作为常量读入,但是由于String池中已经有了"s1"所以这一次不会在String池中创建对象了,而执行new时是必须要创建对象的,所以执行String s2=new String("s1");时创建了一个对象。看下面两段代码:
String s2 = new String("s1"); //创建一个对象,并且以后每执行一次创建一个对象,一个引用
String s4 = "xyz"; //不创建对象,只是创建一个新的引用
Java基础之String中equals,声明方式,等大总结的更多相关文章
- java基础解析系列(十一)---equals、==和hashcode方法
java基础解析系列(十一)---equals.==和hashcode方法 目录 java基础解析系列(一)---String.StringBuffer.StringBuilder java基础解析系 ...
- Java基础之String、StringBuffer、StringBuilder浅析
Java基础之String.StringBuffer.StringBuilder浅析 一.前言: 位于java.lang包下的String.StringBuilder.StringBuffer一般都是 ...
- Java 字符串比较,String 中的一些方法 == 和 equals 的详解
"==" 是比较的是两个对象的内存地址,而equals方法默认情况下是比较两个对象的内存地址. 1.String str = "hello" 生成的字符串,首 ...
- java基础63 JavaScript中的Number、Math、String、Date对象(网页知识)
本文知识点(目录): 1.Number对象 2.Math对象 3.String对象 4.Date对象 (日历例子) 1.Number对象 1.1.Number对象的创建方式 方式1: ...
- 【Java基础】String 相关知识点总结
String 相关知识点总结 字符串的不可变性 概述 String 被声明为 final,因此它不可继承 在 Java8 中,String 内部使用 char 数组存储数据 public final ...
- Java基础:hashCode与equals个人学习记录
摘要: 本文主要记录本人对hashCode和对equals两个知识点的学习过程. 从学生时期初学java,就知道hashCode和equals这两个方法,工作中equals方法使用也是特别频繁,要说e ...
- Spring基础——IOC九种bean声明方式
Spring简介 Spring不是服务于开发web项目的功能,或业务.而是服务于项目的开发,方便各层间的解耦调用,方便对类的批量管理,是提高软件开发效率,降低后期维护成本的框架. Spring的核心思 ...
- Java 基础之 String 类
String String 被声明为 final,因此不能被继承.(Integer 等包装类也不能被继承) 在 java8 中,String 内部使用 char 数组 来存储数据 public fin ...
- String基础: String两种创建对象方式的比较
字符串常量 在一般的语言中常量一旦声明则不可改变,在java中的字符串常量是以匿名对象来表示的 javaz中字符串两种定义方法: String strA= new String("hello ...
随机推荐
- layer 父弹窗获取子弹窗内的dom节点元素和变量
1 var body = layer.getChildFrame('body', index); //获取子弹窗的dom节点 2 3 var iframeWin = window[layero.fin ...
- 1. 揭秘Spring类型转换 - 框架设计的基石
仰不愧天,俯不愧人,内不愧心.关注公众号[BAT的乌托邦],有Spring技术栈.MyBatis.JVM.中间件等小而美的原创专栏供以免费学习.分享.成长,拒绝浅尝辄止.本文已被 https://ww ...
- 痞子衡嵌入式:一个奇怪的Keil MDK下变量链接强制对齐报错问题(--legacyalign)
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是一个奇怪的Keil MDK下变量链接强制对齐报错问题. 痞子衡最近一直在参与恩智浦SBL项目(就是一个适用LPC和i.MXRT的完整OT ...
- WireShark抓包分析以及对TCP/IP三次握手与四次挥手的分析
WireShark抓包分析TCP/IP三次握手与四次挥手 Wireshark介绍: Wireshark(前称Ethereal)是一个网络封包分析软件.功能十分强大,是一个可以在多个操作系统平台上的开源 ...
- UML第一次个人作业
这个作业属于哪个课程 https://api.jihuayu.site/cnblogs 这个作业要求在哪里 https://edu.cnblogs.com/campus/fzzcxy/2018SE1/ ...
- PyQt(Python+Qt)学习随笔:QDockWidget停靠部件floating和features属性
专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 1.floating属性 floating属性表示QDockWidge ...
- 第二章、PyQt5应用构建详细过程介绍
老猿Python博文目录 老猿Python博客地址 一.引言 在上节<第一章.PyQt的简介.安装与配置>介绍了PyQt5及其安装和配置过程,本节将编写一个简单的PyQt5应用,介绍基本的 ...
- jmeter使用中的问题
1.响应乱码 step1:指定请求节点下,新建后置控制器"BeanShell PostProcessor" step2:其脚本框中输入以下代码,保存 //获取响应代码Unicode ...
- 小心使用 Task.Run 解惑篇
继上一篇文章之后,这篇文章主要解答以下两个疑惑: 由于值类型是拷贝的方式赋值,所以捕获的本地变量和类成员是指向的是各自的值,对本地变量的捕获不会影响到整个类.但如果把 _id 改为引用类型(如 Str ...
- MySQL技术内幕InnoDB存储引擎(四)——表相关
表是什么? 就是关于特定实体地数据集合,是关系型数据库模型地核心. 索引组织表 什么是索引组织表? 表中数据都是根据主键的顺序组织存放的,这种存储方式就是索引组织表.就是存储在一个索引结构中的表. 也 ...