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 ...
随机推荐
- shell中,我们可以通过简单的一个判断来判断命令是否存在
shell中,我们可以通过简单的一个判断来判断命令是否存在 which "Command" > /dev/null if [ $? -eq 0 ] then echo com ...
- Maven的安装、配置及使用入门+maven安装报错:JAVA_HOME【申明:来源于网络】
Maven的安装.配置及使用入门+maven安装报错:JAVA_HOME[申明:来源于网络] Maven的安装.配置及使用入门:http://www.cnblogs.com/dcba1112/arch ...
- BEM的命名规则
给自己提个醒,别乱命名了
- linux --- Ansible篇
ansible背景 1.什么是ansible? ansible是新出现的自动化运维工具,基于Python开发,集合了众多运维工具(puppet.cfengine.chef.func.fabric)的优 ...
- 几个bat文件(关于robot freamwork安装)
如果安装后 没有这几文件,或者在运行后 提示 文件缺少这个文件 , 就需要手动创建. 一般文件在 :C:\Python27\Scripts 这个目录下 1.pybot.bat文件: @echo o ...
- 在队列中join()与task_done()的关联性
1.基础解释: Queue.task_done() 在完成一项工作之后,Queue.task_done()函数向任务已经完成的队列发送一个信号 Queue.join() 实际上意味着等到队列为空,再执 ...
- linux基础命令--userdel 删除用户帐户和相关文件
描述 userdel命令用于删除用户帐户和相关文件. userdel命令修改系统账户文件,删除所有涉及用户的信息,指定的用户(LOGIN)必须存在. 语法 userdel [options] LOGI ...
- centos7最小化安装系统
https://blog.csdn.net/hellboy0621/article/details/80392273
- go基本语法
1. 用var来定义变量, 类型被纺织在变量名的后面. var i int 并且运行时默认初始化为二进制0 var i , y int var x string, y int2. 显示初始化值的时候, ...
- Fiddler抓包【6】_Fiddler Script
1.安装SyntaxView插件 使用Fiddler Script前需要安装SyntaxView插件: 方式1:Inspectors tab--->Get SyntaxView tab---&g ...