- 浏览: 311107 次
- 性别:
- 来自: 石家庄
文章分类
最新评论
-
837718860:
之前总会看到不定长参数,现在大概知道意思了。
简单介绍Java的不定长度参数 -
kjstart:
因为当LRU用你就可以从头删了
LinkedHashMap 用法 -
chico:
一直对maven了解不多,准备借鉴一下。
Struts+Spring+Hibernate注解零配置整合 -
shmily2038:
建议写点源码安装的,这个没难度
Centos6下安装和配置mysql-server -
jy34521:
谢谢 ,学到很多东西
Struts+Spring+Hibernate注解零配置整合
原文链接
Constant Pool常量池的概念:
在讲到String的一些特殊情况时,总会提到String Pool或者Constant Pool,但是我想很多人都不太明白Constant Pool到底是个怎么样的东西,运行的时候存储在哪里,所以在这里先说一下Constant Pool的内容。
String Pool是对应于在Constant Pool中存储String常量的区域.习惯称为String Pool,也有人称为String Constant Pool.好像没有正式的命名。
在java编译好的class文件中,有个区域称为Constant Pool,他是一个由数组组成的表,类型为cp_info constant_pool[],用来存储程序中使用的各种常量,包括Class/String/Integer等各种基本Java数据类型,详情参见The Java Virtual Machine Specification 4.4章节。
对于Constant Pool,表的基本通用结构为:
tag是一个数字,用来表示存储的常量的类型,例如8表示String类型,5表示Long类型,info[]根据
类型码tag的不同会发生相应变化。
对于String类型,表的结构为:
tag固定为8,string_index是字符串内容信息,类型为:
tag固定为1,length为字符串的长度,bytes[length]为字符串的内容。
(以下代码在jdk6中编译)
为了详细理解Constant Pool的结构,我们参看一些代码:
由于"sss111"和"sss222"都是字符串常量,在编译期就已经创建好了存储在class文件中。
在编译后的class文件中会存在这2个常量的对应表示:
08 00 11 01 00 06 73 73 73 31 31 31 08 00 13 01 ; ......sss111....
00 06 73 73 73 32 32 32 ; ..sss222
根据上面说的String常量结构,我们分析一下:
开始的08为CONSTANT_String_info结构中的tag,而11应该是它的相对引用,01为CONSTANT_Utf8_info的tag,06为对应字符串的长度,73 73 73 31 31 31为字符串对应的编码,接着分析,会发现后面的是对应"sss222"的存储结构。
经过上面分析,我们知道了11和13是两个字符串的相对引用,就可以修改class文件来修改打印的内容,把class文件中的00 6E 00 04 00 03 00 00 00 24 12 10 4C 12 12 4D改成00 6E 00 04 00 03 00 00 00 24 12 10 4C 12 10 4D,程序就会输出sss111 sss111,而不是和原程序一样输出sss111 sss222,因为我们把对"sss222"的相对引用12改成了对"sss111"的相对引用10。
在上面程序中存在2个相同的常量"sss111",对于n个值相同的String常量,在Constant Pool中只会创建一个,所以在编译好的class文件中,我们只能找到一个对"sss111"的表示:
000000abh: 08 00 11 01 00 06 73 73 73 31 31 31 ; ......sss111
在程序执行的时候,Constant Pool会储存在Method Area,而不是heap中。
另外,对于""内容为空的字符串常量,会创建一个长度为0,内容为空的字符串放到Constant Pool中,
而且Constant Pool在运行期是可以动态扩展的。
关于String类的说明
1.String使用private final char value[]来实现字符串的存储,也就是说String对象创建之后,就不能再修改此对象中存储的字符串内容,就是因为如此,才说String类型是不可变的(immutable)。
2.String类有一个特殊的创建方法,就是使用""双引号来创建.例如new String("i am")实际创建了2个
String对象,一个是"i am"通过""双引号创建的,另一个是通过new创建的.只不过他们创建的时期不同,
一个是编译期,一个是运行期!
3.java对String类型重载了+操作符,可以直接使用+对两个字符串进行连接。
4.运行期调用String类的intern()方法可以向String Pool中动态添加对象。
String的创建方法一般有如下几种
1.直接使用""引号创建;
2.使用new String()创建;
3.使用new String("someString")创建以及其他的一些重载构造函数创建;
4.使用重载的字符串连接操作符+创建。
例1
例2
例3
例4
例5
这个是The Java Language Specification中3.10.5节的例子,有了上面的说明,这个应该不难理解了
输出结果为true true true true false true,请自行分析!
结果上面分析,总结如下:
1.单独使用""引号创建的字符串都是常量,编译期就已经确定存储到String Pool中;
2.使用new String("")创建的对象会存储到heap中,是运行期新创建的;
3.使用只包含常量的字符串连接符如"aa" + "aa"创建的也是常量,编译期就能确定,已经确定存储到String Pool中;
4.使用包含变量的字符串连接符如"aa" + s1创建的对象是运行期才创建的,存储在heap中;
5.使用"aa" + s1以及new String("aa" + s1)形式创建的对象是否加入到String Pool中我不太确定,可能是必须调用intern()方法才会加入,希望高手能回答!
还有几个经常考的面试题:
1.
上面创建了几个String对象?
答案:3个 ,编译期Constant Pool中创建1个,运行期heap中创建2个.
2.
s1指向的对象中的字符串是什么?
答案: "s1"
Constant Pool常量池的概念:
在讲到String的一些特殊情况时,总会提到String Pool或者Constant Pool,但是我想很多人都不太明白Constant Pool到底是个怎么样的东西,运行的时候存储在哪里,所以在这里先说一下Constant Pool的内容。
String Pool是对应于在Constant Pool中存储String常量的区域.习惯称为String Pool,也有人称为String Constant Pool.好像没有正式的命名。
在java编译好的class文件中,有个区域称为Constant Pool,他是一个由数组组成的表,类型为cp_info constant_pool[],用来存储程序中使用的各种常量,包括Class/String/Integer等各种基本Java数据类型,详情参见The Java Virtual Machine Specification 4.4章节。
对于Constant Pool,表的基本通用结构为:
cp_info { u1 tag; u1 info[]; }
tag是一个数字,用来表示存储的常量的类型,例如8表示String类型,5表示Long类型,info[]根据
类型码tag的不同会发生相应变化。
对于String类型,表的结构为:
CONSTANT_String_info { u1 tag; u2 string_index; }
tag固定为8,string_index是字符串内容信息,类型为:
CONSTANT_Utf8_info { u1 tag; u2 length; u1 bytes[length]; }
tag固定为1,length为字符串的长度,bytes[length]为字符串的内容。
(以下代码在jdk6中编译)
为了详细理解Constant Pool的结构,我们参看一些代码:
String s1 = "sss111"; String s2 = "sss222"; System.out.println(s1 + " " + s2);
由于"sss111"和"sss222"都是字符串常量,在编译期就已经创建好了存储在class文件中。
在编译后的class文件中会存在这2个常量的对应表示:
08 00 11 01 00 06 73 73 73 31 31 31 08 00 13 01 ; ......sss111....
00 06 73 73 73 32 32 32 ; ..sss222
根据上面说的String常量结构,我们分析一下:
开始的08为CONSTANT_String_info结构中的tag,而11应该是它的相对引用,01为CONSTANT_Utf8_info的tag,06为对应字符串的长度,73 73 73 31 31 31为字符串对应的编码,接着分析,会发现后面的是对应"sss222"的存储结构。
经过上面分析,我们知道了11和13是两个字符串的相对引用,就可以修改class文件来修改打印的内容,把class文件中的00 6E 00 04 00 03 00 00 00 24 12 10 4C 12 12 4D改成00 6E 00 04 00 03 00 00 00 24 12 10 4C 12 10 4D,程序就会输出sss111 sss111,而不是和原程序一样输出sss111 sss222,因为我们把对"sss222"的相对引用12改成了对"sss111"的相对引用10。
public class Test { public static void main(String[] args) { String s1 = "sss111"; String s2 = "sss111"; } }
在上面程序中存在2个相同的常量"sss111",对于n个值相同的String常量,在Constant Pool中只会创建一个,所以在编译好的class文件中,我们只能找到一个对"sss111"的表示:
000000abh: 08 00 11 01 00 06 73 73 73 31 31 31 ; ......sss111
在程序执行的时候,Constant Pool会储存在Method Area,而不是heap中。
另外,对于""内容为空的字符串常量,会创建一个长度为0,内容为空的字符串放到Constant Pool中,
而且Constant Pool在运行期是可以动态扩展的。
关于String类的说明
1.String使用private final char value[]来实现字符串的存储,也就是说String对象创建之后,就不能再修改此对象中存储的字符串内容,就是因为如此,才说String类型是不可变的(immutable)。
2.String类有一个特殊的创建方法,就是使用""双引号来创建.例如new String("i am")实际创建了2个
String对象,一个是"i am"通过""双引号创建的,另一个是通过new创建的.只不过他们创建的时期不同,
一个是编译期,一个是运行期!
3.java对String类型重载了+操作符,可以直接使用+对两个字符串进行连接。
4.运行期调用String类的intern()方法可以向String Pool中动态添加对象。
String的创建方法一般有如下几种
1.直接使用""引号创建;
2.使用new String()创建;
3.使用new String("someString")创建以及其他的一些重载构造函数创建;
4.使用重载的字符串连接操作符+创建。
例1
String s1 = "sss111"; //此语句同上 String s2 = "sss111"; System.out.println(s1 == s2); //结果为true
例2
String s1 = new String("sss111"); String s2 = "sss111"; System.out.println(s1 == s2); //结果为false
例3
String s1 = new String("sss111"); s1 = s1.intern(); String s2 = "sss111"; System.out.println(s1 == s2);
例4
String s1 = new String("111"); String s2 = "sss111"; String s3 = "sss" + "111"; String s4 = "sss" + s1; System.out.println(s2 == s3); //true System.out.println(s2 == s4); //false System.out.println(s2 == s4.intern()); //true
例5
这个是The Java Language Specification中3.10.5节的例子,有了上面的说明,这个应该不难理解了
package testPackage; class Test { public static void main(String[] args) { String hello = "Hello", lo = "lo"; System.out.print((hello == "Hello") + " "); System.out.print((Other.hello == hello) + " "); System.out.print((other.Other.hello == hello) + " "); System.out.print((hello == ("Hel"+"lo")) + " "); System.out.print((hello == ("Hel"+lo)) + " "); System.out.println(hello == ("Hel"+lo).intern()); } } class Other { static String hello = "Hello"; } package other; public class Other { static String hello = "Hello"; }
输出结果为true true true true false true,请自行分析!
结果上面分析,总结如下:
1.单独使用""引号创建的字符串都是常量,编译期就已经确定存储到String Pool中;
2.使用new String("")创建的对象会存储到heap中,是运行期新创建的;
3.使用只包含常量的字符串连接符如"aa" + "aa"创建的也是常量,编译期就能确定,已经确定存储到String Pool中;
4.使用包含变量的字符串连接符如"aa" + s1创建的对象是运行期才创建的,存储在heap中;
5.使用"aa" + s1以及new String("aa" + s1)形式创建的对象是否加入到String Pool中我不太确定,可能是必须调用intern()方法才会加入,希望高手能回答!
还有几个经常考的面试题:
1.
String s1 = new String("s1") ; String s2 = new String("s1") ;
上面创建了几个String对象?
答案:3个 ,编译期Constant Pool中创建1个,运行期heap中创建2个.
2.
String s1 = "s1"; String s2 = s1; s2 = "s2";
s1指向的对象中的字符串是什么?
答案: "s1"
发表评论
-
扑朔迷离的Java浮点数
2012-12-28 23:39 2145摘要 Java浮点数的定义大体上遵守了二进制浮点运算标准( ... -
MyBatis连Access/DBF时,出现的java.sql.SQLException: No data found
2012-09-04 17:49 2815今天我们开发时,遇到一异常 org.springframewo ... -
XStream no-args constructor
2013-02-27 11:34 3781今天工作中遇到了这个问题: com.thoughtw ... -
Java 单例模式 工具类
2010-08-26 13:23 5451本文版权归作者所有,仅供用来网上学习来用,读者可以收藏,请不要 ... -
java 反射生成对象 工具类
2010-07-22 16:15 4348本文版权归作者所有,仅供用来网上学习来用,读者可以收藏,请不要 ... -
LinkedHashMap 用法
2010-07-15 11:23 22380近日用到了LinkedHashMap。用此Map的意图在于此M ... -
Java 自定义 ClassLoader 加载jar
2010-07-14 21:35 5318本文版权归作者所有,仅供用来网上学习来用,读者可以收藏,请不要 ... -
Java 反射 获取范型中的参数
2010-07-07 10:42 2600近日,需要用Annotation(注解)来实现对象的数据Cop ... -
正则表达式汇总
2010-04-24 11:42 828验证数字的正则表达式集 验证数字:^[0-9]*$ ... -
图形与java2D小结与经验
2009-09-26 15:46 1548原文链接 1.坐标系统是确定屏幕上每个点的一个方案。 2. ... -
私有构造函数产生对象
2009-09-26 15:36 1031原文链接 import java.lang.reflect ... -
JAVA中的反射机制
2009-09-26 15:23 893原文链接 import java.lang.reflect ... -
java线程的死锁
2009-09-26 15:10 910原文链接 public class DeadLock i ... -
利用Java的反射机制编写的可以扩展任意数组大小的方法
2009-09-26 15:01 1250原文链接 import java.lang.reflec ... -
java字符串的各种编码转换
2009-09-24 23:53 3266原文链接 import java.io.Unsuppor ... -
Java编译器对于String常量表达式的优化
2009-09-24 23:50 751[url=http://java.ccidnet.com/ar ... -
org.apache.commons.lang.StringUtil的使用
2009-09-24 23:11 1241原文链接 StringUtil包函数 1.空字符串检查 ... -
创建String对象过程中【内存分配】的终极权威详尽解释
2009-09-24 22:47 1067原文链接 前不久,一个IBM面试题的帖子引发了很多关于创建S ... -
Hashtable和HashMap的区别
2009-09-24 22:43 12261.Hashtable是Dictionary的子类,HashM ... -
cglib动态代理
2009-09-24 22:35 1019原文链接 cglib是个好东东,说牛刀,是因为它很强大,用途很 ...
相关推荐
掌握String字符串对象的创建 掌握字符串对象的输入与输出 一般程序需要处理大量文本数据Java语言的文本数据被保存为字符或字符串类型。 若干个字符在计算机里面如何存储? 如何引用呢? 引入 例如 ...
Java中将字符串作为String类型对象来处理。当创建一个String对象时,被创建的字符串是不能被改变的。每次需要改变字符串时都要创建一个新的String对象来保存新的内容。原始的字符串不变。之所以采用这种方法是因为...
创建一个 Gson对象在调用其toJson方法将JAVA对象或集合转换成json字符串 Gson gson = new Gson(); String toJson = gson.toJson(Object o);
String类使用(创建字符串对象、比较、长度、连接、截取、查找和替换、切割和拆分、和其他类型的转换、格式化、判断、手动入池、其他操作) StringBuffer类 StringBuilder类 String、StringBuffer和StringBuilder的...
JAVA 中的字符串处理及类的应用,希望能帮助到你们。
由于String类是不可变的,对字符串进行操作时需要创建新的字符串对象,这可能会导致性能问题。StringBuilder类是可变的,可以避免这种问题,因此它的性能比String类更好。 三、String类和StringBuffer类有什么区别?...
4、 给定的字符串数组:strings s[] = {“string”,”starting”,”strong”,”street”,”stir”,”studeng”,”soft”,”sting”},编写应用程序,统计以”st”开头的字符串有多少个,以”ng”结尾的字符串有多少个...
String对象是不可变的。JVM对其做了一个优化,在内存中开辟了一段区域作为字符串常量池。通过"字面量"形式创建的字符串对象都会缓存并重用。
创建字符串对象 Java语言程序设计(第3版) Java语言程序设计(第3版)第06章-字符串全文共31页,当前为第4页。 6.1.1 字符串基本操作 Java语言程序设计(第3版) 字符串在内存的表示。设有下面声明: String str = new ...
字符串对象的创建方法;Interned String;Interned String;Interned String;取得字符串的长度;按照位置取得指定字符;遍历字符串;练习;下标越界异常;获取子字符串;获取子字符串;练习;查找字符或子串;查找字符或子串;...
字符串在java程序中被大量使用,为了避免每次都创建相同的字符串对象及内存分配,JVM内部对字符串对象的创建做了一定的优化,在Permanent Generation中专门有一块区域用来存储字符串常量池(一组指针指向Heap中的...
文章目录字符串一、String 类1.1 声明字符串1.2 创建字符串二、连接字符串2.1 连接多个字符串2.2 连接其他数据类型三、获取字符串信息3.1 获取字符串长度3.2 字符串查找3.3 获取指定索引位置的字符四、字符串操作4.1...
Java-String类的常用方法总结,String类在java.lang包中,java使用String类创建一个字符串变量,字符串变量属于对象。java把String类声明的final类,不能有类。String类对象创建后不能修改,由0或多个字符组成,包含...
它是不可变的,也就是说一旦创建了一个字符串对象,它的值就不能被修改。字符串类提供了许多方法来操作字符串,包括拼接、比较、截取和搜索等。 可以使用字符串字面值来创建字符串对象,例如: String str = ...
一、字符串的创建 创建一个字符串有几种方法。 1、简单的是用引号将一组字符包含起来 var myStr = "Hello, String!";// 在js中单双引号没有区别 2、可使用如下语句:var myStr1 = new String("Hello,...
(1)字符串对象的创建 例1: var str="Hello world"; 或者 var str=new String("Hello world") (2)charAt()方法 charAt()方法用于返回指定位置的字符串,比如我们想返回str字符串中,第二个字符,则可以写成...
2)按顺序往集合中添加5个字符串对象:"张三"、"李四"、"王五"、"马六"、"赵七"; 3)对集合进行遍历,分别打印集合中的每个元素的位置与内容; 4)打印集合的大小,然后删除集合中的第3个元素,并显示删除元素的...
在讲Jvm对字符串的处理之前,我们先来讲一下,在Java中,常见的5种创建对象的方式: 1)通过关键字new调用构造器创建Java对象,eg:String str = new String("hello"); 2)通过Class对象的newInstance()...
String类提供了多种构造方法,用于创建不同类型的字符串对象,包括直接赋值、字符数组、字节数组等。 常用的String构造方法 常用的String构造方法有直接赋值、字符数组构造和字节数组构造,这些方法能够快速创建出...