java字符串对象存储机制
String s1="abc";创建了几个String对象 ?
String s2 = new String("abc");创建了几个String对象?
s1==s2?
首先需要明确下面的知识点:
1、引用变量与对象的区别;
2、字符串文字"abc"是一个String对象;
3、文字池(pool of literal strings)和堆(heap)中的字符串对象。
一、引用变量与对象
A aa;
这个语句声明一个类A的引用变量aa[我们常常称之为句柄],而对象一般通过new创建。所以题目中s1仅仅是一个引用变量,它不是对象。
二、堆内存和常量池中的字符串对象 是不同的对象,有着不同的地址(回答第三个问题)
String ss1="abc";
String s1=new String("abc"); System.out.println("s1==ss1="+s1==ss1);
输出结果为false。
三、字符串对象的创建(回答第一个问题)
由于字符串对象的大量使用(它是一个对象,一般而言对象总是在heap分配内存),Java中为了节省内存空间和运行时间(如比较字符串时,==比equals()快),在编译阶段就把所有的字符串文字放到一个文字池(pool of literal strings)中,而运行时文字池成为常量池的一部分。文字池的好处,就是该池中所有相同的字符串常量被合并,只占用一个空间。
下面利用一个程序实例,来演示相同的字符串占用同一个空间:
import java.util.*;
import java.io.*;
public class Test{
public static void main(String args[]){
String s1=”abc“; String s2=”abc“;
System.out.println(s1==s2);
}
}
上面的程序段执行时会输出true,这表明s1和s2占用相同的内存空间。此时便可以回答第一个问题了,
String s="abc"定义了一个或0个对象。定义s1时pool中还没有"abc",所以它定义了一个对象"abc"并将其放入到pool中;
定义s2时pool中已经有"abc"了,所以它定义了0个对象。(注:在采用这种形式的表达式定义s时,他只在pool中定义对象,不会在heap中定义)
四、第二个问题的答案
首先将结论告诉读者,String s=new String("abc")定义了两个或者一个对像。
下面对其进行分析
import java.util.*;
import java.io.*;
public class Test{
public static void main(String args[]){
String s1=new String("abc");
String ss1="abc";
String s2=new String("abc");
String ss2="abc";
System.out.println(s1==s2);
System.out.println(ss1==ss2); System.out.println("s1==ss1="+s1==ss1); }
}
这个程序会依次输出False和true和false;对于s1,对其定义时pool中没有"abc",String s1=new String("abc")会先后在pool中和heap中定义"abc",所以它创建了两个对象;而对于s2,它只在heap中定义了一个"abc",所以它创建了一个对象;而对于ss1和ss2,他们定义的时候pool中已经有了"abc",所以定义了0个对象。
java字符串对象存储机制的更多相关文章
- Java基础-String 存储机制管理
JVM运行的时候,将内存分为两个部分,一部分是堆,一部分是栈.堆中存放的是创建对象,而栈中存放的则是方法调用过程中的局部变量或引用.在设计JAVA字符串对象内存实现的时候,在堆中又开辟了一块很小的内存 ...
- java 复制对象 (克隆接口 与 序列化)
关于java对象复制我们在编码过程经常会碰到将一个对象传递给另一个对象,java中对于基本型变量采用的是值传递,而对于对象比如bean传递时采用的是应用传递也就是地址传递,而很多时候对于对象传递我们也 ...
- C++和JAVA实例化对象的区别
JAVA: A a = new A(); 为A对象创建了一个实例,但在内存中开辟了两块空间:一块空间在堆区,存放new A()这个对象:另一块空间在堆栈,也就是栈,存放a,a的值为new A()这个对 ...
- Java中对象与引用
初学Java 时.在非常长一段时间里,总认为基本概念非常模糊. 后来才知道.在很多Java 书中.把对象和对象的引用混为一谈. 假设分不清对象与对象引用,那实在没法非常好地理解以下的面向对象技术.把自 ...
- Java字符串面试问答
字符串是使用最广泛的Java的类之一.在这里,我列出了一些重要的Java的字符串面试问答. 这将有助于您全面了解String并解决面试中与String有关的任何问题. Java基础面试问题 Java中 ...
- java基础-对象的初始化
一 前言 本节内容将会提到方法重载,对象的初始化,对象的构造器,和this关键字的使用,以及会简要的概括一下java中对象回收机制.觉得文章不错的读者可以关注一下作者的博客和公众号(同博客名称) 二 ...
- 为什么Java字符串是不可变对象?
转自 http://developer.51cto.com/art/201503/468905.htm 本文主要来介绍一下Java中的不可变对象,以及Java中String类的不可变性,那么为什么Ja ...
- 对象存储在什么地方(java编程思想)
用引用操作对象.创建了一个引用,需要进行初始化(与事物进行关联),才能正常使用.new将引用于对象进行关联 对象存储到什么地方? 程序运行时,对象是怎么进行放置安排的呢?特别是内存是怎么分配的呢?对这 ...
- 【JAVA - 基础】之String存储机制浅析
本文主要解决以下几个问题 String源码解析? String和new String的区别? String通过"+"或concat累加时的对象创建机制? StringBuilder ...
随机推荐
- javascript的数组之reduce()
reduce()方法对累加器和数组中的每个元素(从左到右)应用到一个函数中,最终得到一个值并返回 const array1 = [1, 2, 3, 4]; const reducer = (accum ...
- Lambda查询
使用EF查询数据库,之前使用Linq表达式,现在改成另一个种方法查询:Lambda表达式 TestEntities db=new TestEntities(); ).FirstOrDefault(); ...
- Vue 前端面试题
Vue 前端面试题 1. 说一下 Vue 的双向绑定数据的原理 vue 实现数据双向绑定主要是:采用数据劫持结合“发布者 - 订阅者”模式的方式,通过 Object.defineProperty() ...
- stm32直流电机驱动与测速代码配套视频资料
说实话就现在的市场应用中stm32已经占到了绝对住到的地位,51已经成为过去式,32的功能更加强大,虽然相应的难度有所增加,但是依然阻止不了大家学习32的脚步,不说大话了这些大家都懂要不然也不会学习s ...
- Head First Python-Python简单处理文件
前面介绍了自定义格式化输出列表函数printList(),下面再介绍下格式化列表项及列表项的排序. 这里有一组列表数据,记录运动员跑步时间的,要求按照时间大小进行排序.这里每项数据记录的时间格式不一样 ...
- 2018-2019-2 网络对抗技术 20165225 Exp5 MSF基础应用
2018-2019-2 网络对抗技术 20165225 Exp5 MSF基础应用 验前准备 本实践目标是掌握metasploit的基本应用方式,重点常用的三种攻击方式的思路.具体需要完成: 一个主动攻 ...
- JSTL将number类型转化为String类型
<c:set var="lm1"> <c:out value="${lm}" /> </c:set>
- Java学习--抽象类和接口
https://www.cnblogs.com/dolphin0520/p/3811437.html 抽象类 先了解一下[抽象方法]—一种特殊的方法,只有声明,没有具体的实现 abstract vo ...
- WIN7远程桌面连接--“发生身份验证错误。要求的函数不受支持”
故障现象:WIN7发现远程桌面无法连接了,报“发生身份验证错误.要求的函数不受支持”的错误: 解决办法:开始菜单->运行gpedit.msc 打开配置项:计算机配置>管理模板>系统& ...
- [svc]tcp三次握手四次挥手&tcp的11种状态(半连接)&tcp的time-wait
TCP的状态转化过程(11种状态)以及TIME_WAIT状态 高性能网络 | 你所不知道的TIME_WAIT和CLOSE_WAIT 我相信很多都遇到过这个问题.一旦有用户在喊:网络变慢了.第一件事情就 ...