Java基础笔记之String相关知识
(二)String
Sring 被声明为 final ,因此不可被继承。
String的不可变性:
看String的定义(java9版本):
public final class String implements java.io.Serializable, Comparable<String>, CharSequence {
/** value为存储TSring字符的字符数组 */
private final byte[] value;
/** 使用Coder标识使用哪种编码 **/
private final byte coder;
}
value被声明为final类型,这意味着 value 数组初始化之后就不能再引用其它数组,并且 String 内部没有改变 value 数组的方法,因此可以保证 String 不可变。
- 不可变的好处:
- 可以缓存 hash 值:
因为 String 的 hash 值经常被使用,例如 String 用做 HashMap 的 key。不可变的特性可以使得 hash 值也不可变,因此只需要进行一次计算。- String Pool 的需要:
如果一个 String 对象已经被创建过了,那么就会从 String Pool 中取得引用。只有 String 是不可变的,才可能使用 String Pool。如下图:
我的理解:比如说 String myName = "Cherish";这个Cherish字符串一旦被创建,就会存到内存上某个地址如 0x58 处,然后这个字符串会被放到String Pool中,之后你再传建一个 String yourName = "Cherish",那么,这个yourName将不会重新分配一块内存并把Cherish存进去,而是,直接指向前面创建的 “Cherish”的内存,以后无论你创建多少个 “Cherish”字符串,他都是指向最初的那个“Cherish”的地址。如下图:
另一边,如果我改变myName的值,则原来保存的值不会改变,而只会另外开辟一块空间,把改变后的字符串存进去,如下图:
- 安全性:
String 经常作为参数,String 不可变性可以保证参数不可变。例如在作为网络连接参数的情况下如果 String 是可变的,那么在网络连接过程中,String 被改变,改变 String 对象的那一方以为现在连接的是其它主机,而实际情况却不一定是。- 线程安全:
String 不可变性天生具备线程安全,可以在多个线程中安全地使用。
String、StringBuffer and StringBuilder(面试考察点,待深入研究)
1.可变性
- String 不可变
- StringBuffer 和 StringBuilder 可变
2.线程安全
- String 不可变,因此是线程安全的
- StringBuilder 不是线程安全的;
- StringBuffer 是线程安全的,内部使用 synchronized 进行同步;
StringPool (面试考察点 new String(“xxx”)和 直接 = “xxx”的区别)
- 字符串常量池(String Pool)保存着所有字符串字面量(literal strings),这些字面量在编译时期就确定。不仅如此,还可以使用 String 的 intern() 方法在运行过程中将字符串添加到 String Pool 中。
- 当一个字符串调用 intern() 方法时,如果 String Pool 中已经存在一个字符串和该字符串值相等(使用 equals() 方法进行确定),那么就会返回 String Pool 中字符串的引用;否则,就会在 String Pool 中添加一个新的字符串,同时在堆里新建new String("XXX"),并返回这个新字符串的对象的引用。
- 创建字符串变量的方式:
String str = new String("Cherish")
;
以这种方式赋值时,JVM会先从字符串实例池中查询是否存在"Cherish"这个对象,若不存在则会在实例池中创建"Cherish"对象,同时在堆中创建"Cherish"这个对象,然后将堆中的这个对象的地址返回赋给引用str,若实例池存在则直接在堆中创建"Cherish"这个对象,然后将堆中的这个对象的地址返回赋给引用str。String str = "Cherish"
;
以这种方式赋值时,JVM会先从String Pool中查询是否存在"Cherish"这个对象,如果存在,直接把String Pool中"Cherish"的地址返回给str。如果不存在,则会在String Pool中创建"Cherish"对象,并把String Pool中该对象的地址返回给str。
3.字符串拼接时用 “+” 号拼接的实际过程,为什么不建议使用?
String str1 = "abc";
str1 = "abc"+"EF";
以上代码的实际过程是:
执行 + 的时候,首先,底层会创建一个 new StringBulider()对象,然后调用该对象的append()方法,来拼接“abc” 和 “EF”. ==> new StringBuilder().append(str1).append("EF");
如果继续拼接其他的字符串时,又会继续创建 new StringBuilder(),继续拼接,每次拼接一个,都新建一个对象,这些对象存放在堆中。
public static void main(String[] args) {
String str1 = "abc";
str1 = str1+"EF";
String str2 = "abcEF";
String str3 = "abcEF";
String str4 = new String("abcEF");
System.out.println(str1 == str2);
System.out.println(str1.equals(str2));
System.out.println(str2 == str3);
System.out.println(str2 == str4);
}
结果:
final关键字(拓展)
final关键字:在Java中,final关键字可以用来修饰类、方法和变量(包括成员变量和局?> 部变量):
- 修饰类:
修饰类当用final去修饰一个类的时候,表示这个类不能被继承。注意:
a. 被final修饰的类,final类中的成员变量可以根据自己的实际需要设计为fianl。
b. final类中的成员方法都会被隐式的指定为final方法。
- 修饰方法:
被final修饰的方法不能被重写
使用final方法的原因有两个。第一个原因是把方法锁定,以防任何继承类修改它的含义;第二个原因是效率。
因此,如果只有在想明确禁止 该方法在子类中被覆盖的情况下才将方法设置为final的。
一个类的private方法会隐式的被指定为final方法- 修饰变量:
- 当final修饰一个基本数据类型时,表示该基本数据类型的值一旦在初始化后便不能发生变化;
- 如果final修饰一个引用类型时,则在对其初始化之后便不能再让其指向其他对象(也就是地址不能改变)了,但该引用所指向的对象的内容是可以发生变化的;
- final修饰一个成员变量(属性),必须要显式初始化;
- final变量和普通变量的区别:
一段代码:
public class Test {
public static void main(String[] args) {
String a = "hello2";
final String b = "hello";
String d = "hello";
String c = b + 2;
String e = d + 2;
System.out.println((a == c)); //true
System.out.println((a.equals(e))); //true
System.out.println((a == e)); //false
}
}
Java基础笔记之String相关知识的更多相关文章
- JAVA基础5——与String相关的系列(1)
与String相关的系列 String, 是JAVA中常见的一个引用类型,且其具有一定的特殊性. String类型被设置为final型,即不可继承,也就不可修改其中的实现. String可以改变吗 S ...
- JAVA基础5——与String相关的系列(2)
差异点比较 String使用+直接拼接 这种情况需要分两种情况来讨论: 1. 都是确定的字符串常量之间进行的+号拼接的时候,由于在编译器就可以确定其具体值了,所以编译器在编译期的时候就会把这些常量拼接 ...
- Java基础笔记 – Annotation注解的介绍和使用 自定义注解
Java基础笔记 – Annotation注解的介绍和使用 自定义注解 本文由arthinking发表于5年前 | Java基础 | 评论数 7 | 被围观 25,969 views+ 1.Anno ...
- 【转】Java基础笔记 – 枚举类型的使用介绍和静态导入--不错
原文网址:http://www.itzhai.com/java-based-notes-introduction-and-use-of-an-enumeration-type-static-impor ...
- Java基础-字符串(String)常用方法
Java基础-字符串(String)常用方法 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.java的API概念 Java的API(API:Application(应用) Pr ...
- 03匿名内部类、eclipse快捷键、String相关知识
03匿名内部类.eclipse快捷键.String相关知识-2018.7.11 1.匿名内部类(只针对重写一个方法时候使用,不能向下转型,因为没有子类类名) new Inter(){ public v ...
- 黑马程序员----java基础笔记上(毕向东)
------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 笔记一共记录了毕向东的java基础的25天课程,分上.中.下 本片为上篇,涵盖前10天课程 1. ...
- 黑马程序员----java基础笔记中(毕向东)
<p>------<a href="http://www.itheima.com" target="blank">Java培训.Andr ...
- Java基础笔记05-06-07-08
五.今日内容介绍 1.方法基础知识 2.方法高级内容 3.方法案例 01方法的概述 * A: 为什么要有方法 * 提高代码的复用性 * B: 什么是方法 * 完成特定功能的代码块. 02方法的定义格式 ...
随机推荐
- 相同域名下的cookie污染
问题描述 本地用同一个tomcat调试两个相同框架的不同项目,在同一个浏览器界面里切换时,A项目的登录会把B项目的登录给踢掉,翻反过来亦如此.通过查看浏览器cookie,发现两个项目的cookie完全 ...
- win10无法在桌面右键快捷打开个性化设置、显示设置,在任务栏右键无法快捷打开任务栏设置
Win+R,输入regedit,定位到HKEY_CURRENT_USER\Software\Classes\ 找到列表中的ms-settings 将其删除即可解决! 转自百度知道
- centos7,python2和python3共存
安装依赖包 yum install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk- ...
- 【Git版本控制】Idea中设置Git忽略对某些文件的版本追踪
在Idea中有些本地文件无需与远程库同步,仅是本地使用.此时就需要将这些文件加入到Git的版本忽略中来. 设置步骤 1.搜索插件 .ignore,并安装 2.增加.gitignore文件 3.配置相应 ...
- Linux系统下安装jdk及环境配置(两种方法)
https://blog.csdn.net/qq_42815754/article/details/82968464 这里介绍两种linux环境下jdk的安装以及环境配置方法在windows系统安装j ...
- 简易解说拉格朗日对偶(Lagrange duality)(转载)
转载自https://www.cnblogs.com/90zeng/p/Lagrange_duality.html,本人觉得讲的非常好! 1.原始问题 假设是定义在上的连续可微函数(为什么要求连续可微 ...
- Java结构讲解
Java结构有顺序结构.选择结构和循环结构. 顺序结构: 是Java的基本结构,除非特别说明,否则按顺序一句一句执行:也是最简单的结构:它是任何一个算法都离不开的一种基本算法结构. 选择结构: 1.i ...
- AssetBundleMaster_ReadMe_CN
在开始使用之前, 建议先导入到一个空的工程里, 通过ReadMe的一步步引导使你对整个框架以及文件结构进行熟悉, 之后再考虑导入到现有工程中使用, 完整看完教程大概需要2个小时左右. 先看看文件夹结构 ...
- hbase配置hdfs的HA之后需要修改的路径
hbase-site.xml中配置了hdfs的一个路径 <property> <name>hbase.rootdir</name> <value>hdf ...
- MyBatis 使用 foreach 批量插入
MyBatis 使用 foreach 批量插入 参考博文 老司机学习MyBatis之动态SQL使用foreach在MySQL中批量插入 使用MyBatis一次性插入多条数据时候可以使用 <for ...