Java基础复习第二天

news2024/10/7 15:21:56

目录

一、字符串

二、不可变的好处

三、String, StringBuffer and StringBuilder的区别

四、字符串池

五、新字符串(“abc”)

一、字符串

        String 被声明为 final,因此它不可被继承。(Integer 等包装类也不能被继承)在 Java 8 中,String 内部使用 char 数组存储数据。

public final class String
   implements java.io.Serializable, Comparable<String>, CharSequence {
   /** The value is used for character storage. */
   private final char value[];
}

在 Java 9 之后,String 类的实现改用 byte 数组存储字符串,同时使用 来标识使用了哪种编码。

public final class String
   implements java.io.Serializable, Comparable<String>, CharSequence {
   /** The value is used for character storage. */
   private final byte[] value;
   /** The identifier of the encoding used to encode the bytes in {@code value}. */
   private final byte coder;
}

value 数组被声明为 final,这意味着 value 数组初始化之后就不能再引用其它数组。并且 String 内部没有改变 value 数组的方法,因此可以保证 String 不可变。

二、不可变的好处

1. 可以缓存 hash 值

因为 String 的 hash 值经常被使用,例如 String 用做 HashMap 的 key。不可变的特性可以使得 hash 值也不可变,因此只需要进行一次计算。

2. 字符串池的需要

如果一个 String 对象已经被创建过了,那么就会从 String Pool 中取得引用。只有 String 是不可变的,才可能使用 String Pool。

 

3. 安全性

String 经常作为参数,String 不可变性可以保证参数不可变。例如在作为网络连接参数的情况下如果 String 是可变的,那么在网络连接过程中,String 被改变,改变 String 的那一方以为现在连接的是其它主机,而实际情况却不一定是。

4. 线程安全

String 不可变性天生具备线程安全,可以在多个线程中安全地使用。

三、String, StringBuffer and StringBuilder的区别

1. 可变性

  • 字符串不可变
  • StringBuffer 和 StringBuilder 可变

2. 线程安全

  • String 不可变,因此是线程安全
  • StringBuilder 不是线程安全的
  • StringBuffer 是线程安全的,内部使用 sync(同步

四、字符串池

字符串常量池(String Pool)保存着所有字符串字面量(literal strings),这些字面量在编译时期就确定。不仅如此,还可以使用 String 的 intern() 方法在运行过程将字符串添加到 String Pool 中。

当一个字符串调用 intern() 方法时,如果 String Pool 中已经存在一个字符串和该字符串值相等(使用 equals() 方法进行确定),那么就会返回 String Pool 中字符串的引用;否则,就会在 String Pool 中添加一个新的字符串,并返回这个新字符串的引用。

下面示例中,s1 和 s2 采用 new String() 的方式新建了两个不同字符串,而 s3 和 s4 是通过 s1.intern() 方法取得同一个字符串引用。intern() 首先把 s1 引用的字符串放到 String Pool 中,然后返回这个字符串引用。因此 s3 和 s4 引用的是同一个字符串。

String s1 = new String("aaa");
String s2 = new String("aaa");
System.out.println(s1 == s2);           // false
String s3 = s1.intern();
String s4 = s1.intern();
System.out.println(s3 == s4);           // true

如果是采用 “bbb” 这种字面量的形式创建字符串,会自动地将字符串放入 String Pool 中。

String s5 = "bbb";
String s6 = "bbb";
System.out.println(s5 == s6);  // true

在 Java 7 之前,String Pool 被放在运行时常量池中,它属于永久代。而在 Java 7,String Pool 被移到堆中。这是因为永久代的空间有限,在大量使用字符串的场景下会导致 OutOfMemoryError 错误。

五、新字符串(“abc”)

使用这种方式一共会创建两个字符串对象(前提是 String Pool 中还没有 “abc” 字符串对象)。

  • “abc” 属于字符串字面量,因此编译时期会在 String Pool 中创建一个字符串对象,指向这个 “abc” 字符串字面量;
  • 而使用 new 的方式会在堆中创建一个字符串对象。

创建一个测试类,其 main 方法中使用这种方式来创建字符串对象。

public class NewStringTest {
   public static void main(String[] args) {
       String s = new String("abc");
   }
}

使用 javap -verbose 进行反编译,得到以下内容:

// ...
Constant pool:
// ...
  #2 = Class              #18            // java/lang/String
  #3 = String             #19            // abc
// ...
 #18 = Utf8               java/lang/String
 #19 = Utf8               abc
// ...
 public static void main(java.lang.String[]);
   descriptor: ([Ljava/lang/String;)V
   flags: ACC_PUBLIC, ACC_STATIC
   Code:
     stack=3, locals=2, args_size=1
        0: new           #2                  // class java/lang/String
        3: dup
        4: ldc           #3                  // String abc
        6: invokespecial #4                  // Method java/lang/String."<init>":(Ljava/lang/String;)V
        9: astore_1
// ...

        在 Constant Pool 中,#19 存储这字符串字面量 “abc”,#3 是 String Pool 的字符串对象,它指向 #19 这个字符串字面量。在 main 方法中,0: 行使用 new #2 在堆中创建一个字符串对象,并且使用 ldc #3 将 String Pool 中的字符串对象作为 String 构造函数的参数。

以下是 String 构造函数的源码,可以看到,在将一个字符串对象作为另一个字符串对象的构造函数参数时,并不会完全复制 value 数组内容,而是都会指向同一个 value 数组。

public String(String original) {
   this.value = original.value;
   this.hash = original.hash;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/704097.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

前端-基础选择器

从今天开始学习下前端的知识-查漏补缺&#xff0c;仅为自己学习记录使用 基础选择器 标签选择器类选择器id 选择器通配符选择器 标签选择器 标签名 {属性名&#xff1a;属性值; }<style>p {color: red;} </style><p>你好&#xff0c;世界</p>类选择…

Unity URP 获取Camera Stack

URP 获取Camera Stack 1.using UnityEngine.Rendering.Universal; 2.Camera.main.GetUniversalAdditionalCameraData().cameraStack

【日志加载 log4j】

日志 笔记记录 1. 日志介绍2. 日志体系结构3.Log4j开发流程4.Log4j组成4.1 Loggers 记录器4.2 Appenders 输出源4.3 Layouts 布局5. 配置文件 log4j.properties 1. 日志介绍 2. 日志体系结构 3.Log4j开发流程 1.引入依赖<dependency><groupId>log4j</groupId>…

爬虫正常用哪种代理比较好?

在进行网络爬虫时&#xff0c;使用代理可以带来许多好处&#xff0c;包括提高请求的可靠性、防止IP封锁、实现匿名浏览等。以下是一些常见的代理类型&#xff0c;你可以根据需要选择最适合的&#xff1a; 免费代理&#xff1a;免费代理可能数量众多&#xff0c;但质量和稳定性参…

Python获取某品牌加盟数据采集实现可视化数据分析

前言 大家早好、午好、晚好吖 ❤ ~欢迎光临本文章 开发环境 : python 3.8 运行代码 pycharm 2022.3 辅助敲代码 jupyter 数据分析使用软件 模块使用 &#xff1a; requests 数据请求模块 需要安装 parsel 数据解析模块 csv pandas pyecharts 第三方模块安装&#xf…

基于Java开发的企业人力资源管理系统(ehr系统)

一、项目介绍 一款全源码可二开&#xff0c;可基于云部署、私有部署的企业级数字化人力资源管理系统&#xff0c;涵盖了招聘、人事、考勤、绩效、社保、酬薪六大模块&#xff0c;解决了从人事招聘到酬薪计算的全周期人力资源管理&#xff0c;符合当下大中小型企业组织架构管理…

BOLD信号的生理建模及其对有效连接的影响

导读 本文提供了BOLD信号生理过程的总体概述(即生成生物物理模型)&#xff0c;包括它们在生理信息动态因果模型(P-DCM)框架下的时间过程特征。BOLD信号主要由顺磁性脱氧血红蛋白的变化决定&#xff0c;而顺磁性脱氧血红蛋白的变化是氧代谢、脑血流量和脑血容量变化共同作用的结…

测试工程师首chatGPT,编写python读取xmind测试用例chatgtp+python+xmind

背景 有用xmind写测试用例的吧&#xff0c;统计一个xmind的条&#xff0c;需要花大量的时间&#xff0c;还有要统计有多少条冒烟的&#xff0c;多少条不通过的&#xff0c;还有通过的条数。 需求 快速使用python&#xff0c;写一个简单的脚本&#xff0c;统计所有xmind节点&…

【IP地址与子网掩码】网络杂谈(19)之IP地址分类与子网掩码的概念

涉及知识点 什么是子网掩码&#xff0c;IP地址的分类&#xff0c;子网掩码的概念&#xff0c;深入了解子网掩码与IP地址,A类&#xff0c;B类&#xff0c;C类&#xff0c;D类&#xff0c;E类ip地址范围。 原创于&#xff1a;CSDN博主-《拄杖盲学轻声码》&#xff0c;更多内容可…

Linux调试笔记

gdb调试----------------------------------------------------------------------------------------- CMakeFile.txt加入set(CMAKE_BUILD_TYPE Debug) gdb ./rknn_MNIST 打断点 b 110/main(行号/函数名) 单步调试 s&#xff08;step&#xff09; 单步跳过 n&#xff08;n…

计算机组成原理(2)_计算机基本组成

计算机组成系列文章目录 第一章 计算机的基本组成 1. 大致简介 2. 计算机基本组成 第二章 计算机的指令和运算 第三章 处理器设计 第四章 存储器和IO系统 文章目录 计算机组成系列文章目录前言参考资料一、组成架构&#xff08;冯/图&#xff09;1. 组成架构2. 冯诺依曼3. 图灵…

力扣 530. 二叉搜索树的最小绝对差 / 783. 二叉搜索树节点最小距离

题目来源 530&#xff1a;https://leetcode.cn/problems/minimum-absolute-difference-in-bst/description/ 783&#xff1a; https://leetcode.cn/problems/minimum-distance-between-bst-nodes/ C题解1&#xff1a;递归法&#xff0c;中序遍历。通过中序遍历将二叉搜索树转…

【Android】Android类加载机制

ClassLoader介绍 任何一个 Java 程序都是由一个或多个 class 文件组成&#xff0c;在程序运行时&#xff0c;需要将 class 文件加载到 JVM 中才可以使用&#xff0c;负责加载这些 class 文件的就是 Java 的类加载机制。ClassLoader 的作用简单来说就是加载 class 文件&#xf…

echarts图表-实现中国地图的绘制

第一步&#xff1a;引入中国地图的json数据&#xff0c;初始化echarts的dom结构&#xff0c;使用registerMap方法加载地图数据&#xff08;注&#xff1a;echarts5.X版本后删除了中国地图的JSON&#xff0c;需自行下载JSON或降低echarts版本&#xff09; 第二步&#xff1a;传输…

React通过props的children实现插槽功能

可能会比较遗憾的说 React中并没有vue中的 slot 插槽概念 不过 可以通过props.children 实现类似功能 我们先创建一个React项目 在src下创建目录components 在下面创建一个dom.jsx组件 参考代码如下 import React from "react" export default class dom extends R…

Android学习日志 一、滚动视图的嵌套

文章目录 滚动视图的嵌套创建项目(前期准备)工程搭建编写XML正式代码 By-Round Moon 滚动视图的嵌套 说明:本博客是博主学习安卓开发的第一个案例。接下来会进行一系列的样例&#xff0c;含很多基础部分&#xff0c;各位观众老爷请见谅。 Android Studio 版本:2022.2.1 patch …

如何将MBR转为GUID?这方法易于使用且安全!

为什么要将MBR转为GUID(GPT)&#xff1f; MBR代表主引导记录&#xff0c;它使用Legacy BIOS分区表。而GPT磁盘&#xff0c;也就是GUID分区表的缩写&#xff0c;是一种引入了统一可扩展固件接口 (UEFI) 的新布局。GPT磁盘有2个主要优势&#xff1a; GPT磁盘每个分区…

前端-CSS 字体和文本样式

字体大小 /* 浏览器默认字体大小 16px */ font-size: 16px;<div style"font-size: 16px;">Hello World!</div> <div style"font-size: 26px;">Hello World!</div>字体粗细 font-weight: 400;<div style"font-weight: no…

JumpServer开源堡垒机页面配置

JumpServer开源堡垒机页面配置 一、登录二、功能模块2.1、控制台2.1.1、用户管理2.1.1.1、用户列表2.1.1.2、用户组 2.1.2、资产管理2.1.2.1、资产列表2.1.2.1.1、创建服务器链接2.1.2.1.2、创建数据库MySQL链接 2.1.2.2、网域列表2.1.2.3、平台列表2.1.2.4、标签列表 2.1.3、账…

同源建模MOE:请叫我永远的神!

同源建模 实/操/篇 1.分子力场的设置 MOE中缺省的分子力场MMFF94x是一个用于小分子和复合物模拟的力场,不能很好地适用于大分子模拟,由于这里我们要进行同源模建,模拟对象是蛋白质结构,因此首先要将缺省分子力场MMFF94x更改为适用于蛋白质模拟的相关分子力场&#xff0c;如A…