首先,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对象的存储位置(学习笔记)的更多相关文章

  1. java中String对象的存储位置

    public class Test { public static void main(String args[]) { String s1 = "Java"; String s2 ...

  2. Java中String对象的不可变性

    首先看一个程序 package reverse; public class Reverse { public static void main(String[] args) { String c1=n ...

  3. Java中String对象创建机制详解()

    一String 使用 private final char value来实现字符串存储 二Java中String的创建方法四种 三在深入了解String创建机制之前要先了解一个重要概念常量池Const ...

  4. JVM 内存分配模型概念和java中各种对象的存储

    JVM 内存分配模型概念 --在工作中可能用到的机会不多,有个概念的了解 --此文是转载某位读者,应该是在阅读了<深入理解Java虚拟机JVM高级特性与最佳实践> 一书后,总结所得.写的不 ...

  5. Javascript中String对象的的简单学习

    第十一课String对象介绍1:属性    在javascript中可以用单引号,或者双引号括起来的一个字符当作    一个字符对象的实例,所以可以在某个字符串后再加上.去调用String    对象 ...

  6. Java中String对象两种赋值方式的区别

    本文修改于:https://www.zhihu.com/question/29884421/answer/113785601 前言:在java中,String有两种赋值方式,第一种是通过“字面量”赋值 ...

  7. java中String常量的存储原理

    相关题目(运行结果在代码注释后面) 1. package StringTest; public class test1 { public static void main(String[] args) ...

  8. Java中String对象的创建

    字符串对象是一种特殊的对象.String类是一个不可变的类..也就说,String对象一旦创建就不允许修改 String类有一个对应的String池,也就是 String pool.每一个内容相同的字 ...

  9. JAVA中 XML与数据库互转 学习笔记三

    要求 必备知识 JAVA基础知识,XML基础知识,数据库的基本操作. 开发环境 MyEclipse10/MySql5.5 资料下载 源码下载   数据库在数据查询,修改,保存,安全等方面与其他数据处理 ...

随机推荐

  1. c++ 数值计算库Eigen

    http://eigen.tuxfamily.org/index.php?title=Main_Page

  2. centos中更新glibc库文件到2.17

    1 确保安装过gcc yum install gcc 2 获取glibc相关版本 wget http://ftp.gnu.org/pub/gnu/glibc/glibc-2.17.tar.xz 3 解 ...

  3. How to sort HashSet in Java

    How to sort HashSet in Java 方法一:By Converting HashSet to List 方法二:By Converting HashSet to TreeSet i ...

  4. 解决element-ui表格表头内容太长时的换行问题

    在用vue+element-ui做一个后台管理系统时,遇到这样的问题, 如图: 使用el-table做一个表格,当表头内容过长时会换行,在不设置的宽度的时候每一列的宽度是等比例分配的,虽然elemen ...

  5. [转帖]中国 GPL 诉讼第一案:关于 GPL 问题的探讨

    中国 GPL 诉讼第一案:关于 GPL 问题的探讨 https://linux.cn/article-11683-1.html 2019 年 11 月初,数字天堂(北京)网络技术有限公司(下称:数字天 ...

  6. 拦截器配置类使用继承写法导致jackson的全局配置失效

    问题描述 项目中需要一个拦截器用于拦截请求,在没有请求中生成requestId.然后写了一个配置类,这个类继承了 WebMvcConfigurationSupport类,重写了addIntercept ...

  7. 小白的C++之路——求质数

    初学C++,打算用博客记录学习的足迹.写了两个求质数的程序,修修改改. #include <iostream> #include <math.h> using namespac ...

  8. Go语言【数据结构】切片

    切片 简介 简单地说,切片就是一种简化版的动态数组.Go 数组的长度不可改变,而切片长度是不固定,切片的长度自然也就不能是类型的组成部分了.数组虽然有适用它们的地方,但是数组的类型和操作都不够灵活,因 ...

  9. 一个萝卜一个坑#M坑—Polynomial、Polyder

    Polynomial 作用:对输入值执行多项式系数计算,输入输出都可为实数标量或向量. 库:Simulink / Math Operations Polyval 作用:多项式计算,即求多项式在某一点的 ...

  10. Java 8——Lambda表达式

    本篇文章不介绍Lambda的前世今生,这里只对Lambda表达的应用做详细了解.以及与内部类的差异点. Lambda表达式 Lambda表达式是Java SE 8版本中引入的新的语法糖.将功能看做方法 ...