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 ...
随机推荐
- C#(二)基础篇—操作符
2020-12-02 本随笔为个人复习巩固知识用,多从书上总结与理解得来,如有错误麻烦指正 1.数学操作符 int a=2,b=3,c=0; float d=0; c=a+b; //c=5 c++; ...
- moviepy音视频剪辑基类VideoClip的write_videofile方法codec、bitrate、preset、audio_bitrate、audio_nbytes等参数的作用
☞ ░ 前往老猿Python博文目录 ░ moviepy音视频剪辑模块的视频剪辑基类write_videofile方法用于将视频剪辑输出到文件,调用语法如下: write_videofile(self ...
- 第11.6节 Python正则表达式的字符串开头匹配模式及元字符“^”(插入符、脱字符)功能介绍
符号"^"为插入符,也称为脱字符,在Python中脱字符表示匹配字符串的开头,即字符串的开头满足匹配模式的要求.这个功能有点类似搜索函数match,只是这是通过搜索模式来指定,而m ...
- 第十八章、QListView/Model开发
老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 一.概述 QListView理论上可以和所有QAbstractItemModel派生的类如QStri ...
- PyQt(Python+Qt)学习随笔:Qt Designer中主窗口对象dockNestingEnabled属性
dockNestingEnabled 属性是确认主窗口的浮动部件(dock widget)是否允许嵌套的一个属性. 如果此属性为False,则浮动部件停靠区域只能包含一个浮动部件(水平或垂直).如果此 ...
- XSS挑战赛(1)
以前囫囵吞枣做过一遍,现在从头再来 第一关网址为:http://127.0.0.1/xss-labs-master/level1.php?name=test 而页面上显示了用户test,name可控, ...
- django 删除数据库表后重新同步的方法
python manage.py sqlmigrate your_app_name 0001 把your_app_name换成自己的app名字即可看到框架自动生成的创建表sql语句,于是我就这样看到了 ...
- C#中SQL SERVER 2008字符数据类型使用心得
一.尽可能使用Varchar,少使用或者不使用Char字符类型 因为char类型输入的数据长度达不到设计长度,会用空格补足,下面是数据表设计图: 下面是编辑前200行的图: 凡是输入的数据长度达不到设 ...
- 原生JS学习之秒表、日历
Tips:涉及知识点:Date setInterval DOM 秒表 效果图: 简单构造出草图 Html代码 1 <!DOCTYPE html> 2 <html> ...
- 小程序view的显示与隐藏
需要在全局数据块中,设定一个控制键. data: { ......//省略其他代码 showView: true }, 然后是在wxml中,view的class中设置2个class,并用三目表达式来进 ...