1、判定定义为String类型的st1和st2是否相等,为什么?

public class Demo2_String {public static void main(String[] args) {String st1 = "abc";String st2 = "abc";System.out.println(st1 == st2);System.out.println(st1.equals(st2));}
}

输出结果:
第一行:true
第二行:true
分析:
先看第一个打印语句,在Java中“==”这个符号是比较运算符,它可以用于基本数据类型和引用数据类型是否相等。如果是基本数据类型,==比较的是值是否相等,如果是引用数据类型,比较的是两个对象的内存地址是否相等。
字符串不属于8中基本数据类型,字符串对象属于引用数据类型,在上面把“abc”同时赋值给了st1和st2两个字符串对象,指向的都是同一个地址,所以第一个打印语句中的比较输出结果是 true
第二个打印语句中的equals的比较,我们知道,equals是Object这个父类的方法,在String类中重写了这个equals方法。在JDK API 1.6文档中找到String类下的equals方法,点击进去可以看大这么一句话“将此字符串与指定的对象比较。当且仅当该参数不为null,并且是与此对象表示相同字符序列的String 对象时,结果才为 true。” 注意这个相同字符序列,在后面介绍的比较两个数组,列表,字典是否相等,都是这个逻辑去写代码实现。由于st1和st2的值都是“abc”,两者指向同一个对象,当前字符序列相同,所以第二行打印结果也为true。
画一个内存图来表示上面的代码:

1)先编译,当前类Demo2_String.class文件加载进入内存的方法区
2)第二步,main方法压入栈内存
3)常量池创建一个“abc”对象,产生一个内存地址
4)然后把“abc”内存地址赋值给main方法里的成员变量st1,这个时候st1根据内存地址,指向了常量池中的“abc”。
5)常量池有这个特点,如果发现已经存在,就不在创建重复的对象
6)运行到代码 Stringst2 =”abc”, 由于常量池存在“abc”,所以不会再创建,直接把“abc”内存地址赋值给了st2
7)最后st1和st2都指向了内存中同一个地址,所以两者是完全相同的。

2、下面这句话在内存中创建了几个对象:

String st1 = new String(“abc”);

分析:

在内存中创建两个对象,一个在堆内存,一个在常量池,堆内存对象是常量池对象的一个拷贝副本。当我们看到了new这个关键字,就要想到,new出来的对象都是存储在堆内存。然后我们来解释堆中对象为什么是常量池的对象的拷贝副本。“abc”属于字符串,字符串属于常量,所以应该在常量池中创建,所以第一个创建的对象就是在常量池里的“abc”。第二个对象在堆内存为啥是一个拷贝的副本呢,这个就需要在JDK API 1.6找到String(String original)这个构造方法的注释:初始化一个新创建的 String 对象,使其表示一个与参数相同的字符序列;换句话说,新创建的字符串是该参数字符串的副本。

**3、判定以下定义为String类型的st1和st2是否相等 **

public class Demo2_String {public static void main(String[] args) {String st1 = new String("abc");String st2 = "abc";System.out.println(st1 == st2);System.out.println(st1.equals(st2));}
}

答案:false 和 true
由于有前面两道提内存分析的经验和理论,所以,我能快速得出上面的答案。比较的st1和st2对象的内存地址,由于st1指向的是堆内存的地址,st2看到“abc”已经在常量池存在,就不会再新建,所以st2指向了常量池的内存地址,所以判断结果输出false,两者不相等。第二个equals比较,比较是两个字符串序列是否相等,由于就一个“abc”,所以完全相等。

4、 判定以下定义为String类型的st1和st2是否相等

public class Demo2_String {public static void main(String[] args) {String st1 = "a" + "b" + "c";String st2 = "abc";System.out.println(st1 == st2);System.out.println(st1.equals(st2));}
}

**答案是:true 和 true **
“a”,”b”,”c”三个本来就是字符串常量,进行+符号拼接之后变成了“abc”,“abc”本身就是字符串常量(Java中有常量优化机制),所以常量池立马会创建一个“abc”的字符串常量对象,在进行st2=”abc”,这个时候,常量池存在“abc”,所以不再创建。所以,不管比较内存地址还是比较字符串序列,都相等。

5、判断以下st2和st3是否相等

public class Demo2_String {public static void main(String[] args) {String st1 = "ab";String st2 = "abc";String st3 = st1 + "c";System.out.println(st2 == st3);System.out.println(st2.equals(st3));}
}

答案:false 和 true
仔细分析“+”号的原理,可以发现这个拼接的原理是由StringBuilder或者StringBuffer类和里面的append方法实现拼接,然后调用 toString() 把拼接的对象转换成字符串对象,最后把得到字符串对象的地址赋值给变量。
所以st1和st2的内存都是指向方法区的 而st3的地址是指向StringBuffer在堆中开辟的对象,然后toString方法把这个对象转化成String类型的对象

关于Java String类的理解相关推荐

  1. java --String类解决面试问题

    2019独角兽企业重金招聘Python工程师标准>>> 1.概述 字符串对象是一种特殊的对象.String类是一个不可变的类..也就说,String对象一旦创建就不允许修改 Stri ...

  2. Java——String类的方法

    Java--String类的方法 String str1 = "abc" 与String str2 = new String("abc")有什么区别? 字符串常 ...

  3. java string.substring 参数,Java,String类中的subString()方法,stringsubstring

    Java,String类中的subString()方法,stringsubstring public class TestStringSubString { // main函数 public stat ...

  4. Java String 常量池理解

    Java String 常量池理解 String:字符串常量池 作为最基础的引用数据类型,Java 设计者为 String 提供了字符串常量池以提高其性能,那么字符串常量池的具体原理是什么,我们带着以 ...

  5. Java String类的相关操作

    Java String类的相关操作 一.如何遍历字符串 //法一 String str="hello world"; for(int i=0;i<str.length();i ...

  6. Java String类的split方法简介

    Java String类的split方法简介 String的split()方法用于按传入的字符或字符串对String进行拆分,返回拆分之后的数组. 1.一般用法 用一般的字符,例如 @ 或 , 等符号 ...

  7. Java String类概述

    Java String类 String类简介 字符串比较 String对象(常量)池 静态常量池 运行时常量池 String类简介 字符串严格意义上来讲并不能算是一个基本数据类型,也就是说没有任何一门 ...

  8. 黑马程序员——Java String类 and 正则表达式(第七篇)

    -----------android培训.java培训.java学习型技术博客.期待与您交流!------------ 虽然老毕视频中把正则表达式放到了最后面才讲,但个人认为他和String功能上有些 ...

  9. 深入理解Java String类

    在Java语言中,所有类似"ABC"的字面值,都是String类的实例:String类位于java.lang包下,是Java语言的核心类,提供了字符串的比较.查找.截取.大小写转换 ...

  10. java string string_深入理解Java:String

    在讲解String之前,我们先了解一下Java的内存结构. 一.Java内存模型 按照官方的说法:Java 虚拟机具有一个堆,堆是运行时数据区域,所有类实例和数组的内存均从此处分配. JVM主要管理两 ...

最新文章

  1. Angela启动步骤
  2. rpmdb open failed 的解决办法
  3. linux 回环接口实现,Linux回环接口-----(loop-back/loopback)
  4. 一个类实现多个接口的demo
  5. mysql gui 比较_Navicat for MySQL与MySQL GUI Tools功能比较
  6. Visual paradigm社区版下载及中文菜单的设置
  7. Leetcode:Palindrome Number
  8. ascii码01100001_ASCII码跟数字
  9. 继上一篇博客--javaweb通过接口来实现多个文件压缩和下载(包括单文件下载,多文件批量下载)
  10. GitBucket管理员添加人员
  11. Linux查询端口是否被占用的四种方法
  12. (转)MySQL命令行--导入导出数据库
  13. BZOJ1853: [Scoi2010]幸运数字(容斥原理)
  14. IDP:云原生的“Jupyter”,让算法团队更高产
  15. 自动基线校正 python_安全运维中基线检查的自动化之ansible工具巧用
  16. 【Python实例第1讲】交叉验证预测曲线的画法
  17. UVA 993 Product of digits
  18. 解决jquery中全选点击第二次不生效的问题与分析
  19. 一个能拖动,能调整大小,能更新bind值的vue指令-vuedragx
  20. 示波器X-Y模式显示利萨如(李沙育)与DIY图像

热门文章

  1. 在MySQL中设计新闻网站_基于MySQL新闻搜索引擎的设计与实现
  2. 3.shell脚本的基础知识
  3. [Trie树] BZOJ3689: 异或之
  4. 美国专利客体适格性判断标准浅析
  5. 黑龙江大学计算机专业考研难吗,黑龙江大学考研难吗
  6. 异步时钟域的亚稳态问题和同步器(四)
  7. android camera预览翻转,android camera yuv帧水平翻转实例
  8. 德意志帝国(第一帝国)(962年-1806年)
  9. 【移动端】企业微信移动app测试实战(2)、(3)
  10. 如何正确利用肢体语言表达自己