Java中String对象的存储位置(学习笔记)
首先,String是final修饰的、immutable对象,它以一个个字符的方式存储在字符数组中。
其次,String类型创建对象有两种方式:①通过字面量赋值:会先去常量池中查找是否存在相同的字符串,若存在,栈中引用直接指定该字符串;若不存在,在常量池中进行缓存,再将栈中引用指向它。②通过new关键字:每次new出来的都是一个新的对象,在堆中开辟空间进行存储。
又因为,在JDK1.7的HotSpot中,已经把原本放在永久代的字符串常量池移出,JDK8元空间彻底取代永久代,此时字符串常量池还在堆,所以String变量是以字符数组的形式储在堆。
证明,str1和str2,指向的是同一个字符数组:
String str1="ab";
String str2=new String("ab");
Field field=str2.getClass().getDeclaredField("value");
field.setAccessible(true);
char[] sum=(char[]) field.get(str2);
sum[0]='w';
System.out.println(str1);//wb
System.out.println(str2);//wb
test直接演示String对象的创建位置:
package test.string.equal; public class Main { /**
* 创建了三个对象,"helloworld对象创建在常量池中",每次new String()都会创建一个对象在堆内存中。
*/
void test() {
String s1="helloworld";
String s2= new String("helloworld");
String s3= new String("helloworld");
}
/**
* 程序只创建一个字符串对象“Java”,存放在常量池中,所以s1==s2 为true
*/
void test1(){
String s1="Java";
String s2="Java";
System.out.println(s1==s2);
} /** 第一个new String("Java"):创建了两个对象,Java创建于常量池中,String对象创建于堆内存中。
* 第二个new String("Java"):由于常量池中有Java对象,所以只需创建一个对象,String对象创建于堆内存中。
* s1与s2分别指向String对象堆内存,所以s1==s2 为false
*/
void test2() {
String s1=new String("Java");
String s2= new String("Java");
System.out.println(s1==s2);
} /** 常量的值在编译的时候就确定了,"hello"、"world"都是常量,因此s2的值在编译的时候也确定了,
* s2指向常量池中的"hello world",所以s1==s2为true
*
*/
void test3() {
String s1="hello world";
String s2="hello "+"world";
System.out.println(s1==s2);
} /** s4由两个String变量相加得到,不能再编译时就确定下来,不能直接引用常量池中的"helloworld"对象,而是在堆内存中创建一个新的String对象并由s4指向
* 所以s1==s4为false
*
*/
void test4() {
String s1="helloworld";
String s2="hello";
String s3="world";
String s4=s2+s3;
System.out.println(s1==s4);
} /** s2与s3被final修饰为宏变量,不可更改,编译器在程序使用该变量的地方直接使用该变量的值进行替代,所以s4的值在编译的时候就为"helloworld"
* 指向常量池中的"helloworld"对象
* 所以s1==s4为true
*
*/
void test5() {
String s1="helloworld";
final String s2="hello";
final String s3="world";
String s4=s2+s3;
System.out.println(s1==s4);
}
public static void main(String[] args) {
Main o = new Main();
o.test1();
o.test2();
o.test3();
o.test4();
o.test5(); }
}
Java中String对象的存储位置(学习笔记)的更多相关文章
- java中String对象的存储位置
public class Test { public static void main(String args[]) { String s1 = "Java"; String s2 ...
- Java中String对象的不可变性
首先看一个程序 package reverse; public class Reverse { public static void main(String[] args) { String c1=n ...
- Java中String对象创建机制详解()
一String 使用 private final char value来实现字符串存储 二Java中String的创建方法四种 三在深入了解String创建机制之前要先了解一个重要概念常量池Const ...
- JVM 内存分配模型概念和java中各种对象的存储
JVM 内存分配模型概念 --在工作中可能用到的机会不多,有个概念的了解 --此文是转载某位读者,应该是在阅读了<深入理解Java虚拟机JVM高级特性与最佳实践> 一书后,总结所得.写的不 ...
- Javascript中String对象的的简单学习
第十一课String对象介绍1:属性 在javascript中可以用单引号,或者双引号括起来的一个字符当作 一个字符对象的实例,所以可以在某个字符串后再加上.去调用String 对象 ...
- Java中String对象两种赋值方式的区别
本文修改于:https://www.zhihu.com/question/29884421/answer/113785601 前言:在java中,String有两种赋值方式,第一种是通过“字面量”赋值 ...
- java中String常量的存储原理
相关题目(运行结果在代码注释后面) 1. package StringTest; public class test1 { public static void main(String[] args) ...
- Java中String对象的创建
字符串对象是一种特殊的对象.String类是一个不可变的类..也就说,String对象一旦创建就不允许修改 String类有一个对应的String池,也就是 String pool.每一个内容相同的字 ...
- JAVA中 XML与数据库互转 学习笔记三
要求 必备知识 JAVA基础知识,XML基础知识,数据库的基本操作. 开发环境 MyEclipse10/MySql5.5 资料下载 源码下载 数据库在数据查询,修改,保存,安全等方面与其他数据处理 ...
随机推荐
- 给定一个数组,求如果排序后,相邻两个元素的最大差值,要求时间复杂度为O(N)
第一种方法: 计数排序后,然后找出两两之间的最大差值 计数排序的时间复杂度是O(N) public class CountSort { public static void main(String[] ...
- NPOI导出 The maximum column width for an individual cell is 255 characters
增加如下代码 ) { arrColWidth[column.Ordinal] = ; } //设置列宽 sheet.SetColumnWidth(column.Ordinal, (arrColWidt ...
- mysql启动报错 "unknown variable 'defaults-file=/etc/my.cnf"
使用指定的my.cnf,而不用默认的/etc/my.cnf文件,可以在启动时,在mysqld_safe后加上参数--default-file=/usr/local/server/mysql2/etc/ ...
- ElasticSearch中的JVM性能调优
ElasticSearch中的JVM性能调优 前一段时间被人问了个问题:在使用ES的过程中有没有做过什么JVM调优措施? 在我搭建ES集群过程中,参照important-settings官方文档来的, ...
- seleium 之 EC 的用法
场景 Expected Conditions的使用场景有2种 直接在断言中使用 与WebDriverWait配合使用,动态等待页面上元素出现或者消失 方法注释 先翻译一下这些方法的用法 title_i ...
- 算法设计与分析(李春保)练习题答案v1
1.1第1 章─概论 1.1.1练习题 1.下列关于算法的说法中正确的有(). Ⅰ.求解某一类问题的算法是唯一的 Ⅱ.算法必须在有限步操作之后停止 Ⅲ.算法的每一步操作必须是明确的,不能有歧义或含义模 ...
- TestNG系列(四)TestNG监听器
前言 监听器实际上是一些预定义的java接口,用户创建这些接口的实现类(即implements某监听接口,并实现里面的方法),并加入到testng中,testng便会在运行的不同时刻调用这些类中你自定 ...
- 配置 Nginx 反向代理 WebSocket
用Nginx给网站做反向代理和负载均衡是广泛使用的一种Web服务器部署技术.不仅能够保证后端服务器的隐蔽性,还可以提高网站部署灵活性. 今天我们来讲一下,如何用Nginx给WebSocket服务器实现 ...
- Git教程-安装与创建版本库
Git是一个分布式版本控制系统,他通过命令行使用的工具,Github是提供Git仓库托管服务的网站 安装参考: https://www.liaoxuefeng.com/wiki/89604348802 ...
- php调用webservice接口,java代码接收不到参数
前段时间做了一个项目的二次开发,有个功能是需要php调用java实现的webservice接口,并传递一些参数给接口,然后按照对方提供的接口说明文档进行传参调用,java那边有接收到请求,但是参数总是 ...