- 浏览: 254624 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (232)
- 瞎扯两句 (8)
- 操作系统 (5)
- 工作笔记 (33)
- 设计模式 (1)
- java (57)
- Java IDE (7)
- hibernate (17)
- oracle (46)
- ms sql (2)
- spring (9)
- struts2 (0)
- javascript (16)
- java_code (2)
- java之集合 (2)
- java之线程 (4)
- java之IO (4)
- java之虚拟机 (6)
- java之异常 (0)
- EJB (4)
- XML (4)
- 数据结构-算法 (2)
- 架构设计 (5)
- 配置信息 (2)
- 阅读笔记 (6)
- IT专业英语 (1)
- PI (0)
- 单元测试 (1)
最新评论
“String倒底奇特在哪里?”关于这个问题本来想放过它的,但听说java面试经常考它,而且博友又给我提了不少珍贵的意见,所以准备在尽点力。
废话到此,下面正式开始
1.请看下面这幅图片:
是否觉得奇怪,在1处为true,2处为false!对java有所了解都知道“s1==s2"比较的并非它们在的值(那时该用:s1.equals(s2)),而是比较他们在内存中的地址!难道s1,s2引用的是内存中的同一个数据,呵呵,正是如此!
由于String对象在编程中使用的极为平凡,故而随着程序的增长,势必造成String常量占有了大量的内存,而且往往包含这大量的冗余。假设String与其他类的特性相同,势必造成如下局面:
从中不难看到,内存中充斥这大量的冗余常量"pig","dog",而实际上我们只需要两个常量就可以了。为了解决这个问题,从而使java更高效的使用内存,JVM留出一块特殊的内存区域——“String常量池”。(对String够优待吧)
所以当编译器遇到String s1 = "pig";时,首先检查String常量池中是否有存在"pig", 如果没有,则将pig放入常量池中,如下图:
继续,当编译器遇到String s2 = "pig";时,首先检查String常量池中是否有存在"pig", 如果发现相同的常量"pig", 则只是把指向常量池中现有的,而不创建任何新的String对象。如下:
到此,我们应该可以弄明白为什么1处运行的结果是true了吧!
同时,我们也可以弄明白我上一篇文章的疑惑了,如果常量池中的发生了变化,则s1,s2将会同时变化,这也太可怕了吧,所以java绝对不允许出现这种情况!这也是我们常说的那句话:String对象不可改变!
PS:由于担心String常量池出现问题,String类被标识为final。
下面这个例子可能更加让你无法质疑,我就不在这里废话了:
public class Test {
public static void main(String[] args) {
String s1 = "pig";
Person person = new Person();
person.name = "pig";
System.out.println(person.name == s1);// 输出为true
}
}
Person.java
public class Person {
public String name;
}
至于2处为false,这表明在String s3 = new String("pig")这种情况下,因为我们使用了new 关键字,所以将在常规内存(非String常量池)中创建了一个新的String对象,并且将引用它(到此和普通的对象一样)。此外,常量"pig"将放置在池内。
众多面试答案中所说的String s3 = new String("pig");创建了两个对象,一个引用(句柄)是否指如下状态:(这里只是猜测,希望哪位高人给个正确答案,或者验证方法,小弟在此先行谢过!)
s3==s4比较的是s3,s4引用对象的地址,自然不相同,所以2处运行为false。
参考资料:《SCJP学习指南》
本文出自 “sunfish 翻车鱼” 博客,请务必保留此出处http://sunfish.blog.51cto.com/417500/113108
废话到此,下面正式开始
1.请看下面这幅图片:
是否觉得奇怪,在1处为true,2处为false!对java有所了解都知道“s1==s2"比较的并非它们在的值(那时该用:s1.equals(s2)),而是比较他们在内存中的地址!难道s1,s2引用的是内存中的同一个数据,呵呵,正是如此!
由于String对象在编程中使用的极为平凡,故而随着程序的增长,势必造成String常量占有了大量的内存,而且往往包含这大量的冗余。假设String与其他类的特性相同,势必造成如下局面:
从中不难看到,内存中充斥这大量的冗余常量"pig","dog",而实际上我们只需要两个常量就可以了。为了解决这个问题,从而使java更高效的使用内存,JVM留出一块特殊的内存区域——“String常量池”。(对String够优待吧)
所以当编译器遇到String s1 = "pig";时,首先检查String常量池中是否有存在"pig", 如果没有,则将pig放入常量池中,如下图:
继续,当编译器遇到String s2 = "pig";时,首先检查String常量池中是否有存在"pig", 如果发现相同的常量"pig", 则只是把指向常量池中现有的,而不创建任何新的String对象。如下:
到此,我们应该可以弄明白为什么1处运行的结果是true了吧!
同时,我们也可以弄明白我上一篇文章的疑惑了,如果常量池中的发生了变化,则s1,s2将会同时变化,这也太可怕了吧,所以java绝对不允许出现这种情况!这也是我们常说的那句话:String对象不可改变!
PS:由于担心String常量池出现问题,String类被标识为final。
下面这个例子可能更加让你无法质疑,我就不在这里废话了:
public class Test {
public static void main(String[] args) {
String s1 = "pig";
Person person = new Person();
person.name = "pig";
System.out.println(person.name == s1);// 输出为true
}
}
Person.java
public class Person {
public String name;
}
至于2处为false,这表明在String s3 = new String("pig")这种情况下,因为我们使用了new 关键字,所以将在常规内存(非String常量池)中创建了一个新的String对象,并且将引用它(到此和普通的对象一样)。此外,常量"pig"将放置在池内。
众多面试答案中所说的String s3 = new String("pig");创建了两个对象,一个引用(句柄)是否指如下状态:(这里只是猜测,希望哪位高人给个正确答案,或者验证方法,小弟在此先行谢过!)
s3==s4比较的是s3,s4引用对象的地址,自然不相同,所以2处运行为false。
参考资料:《SCJP学习指南》
本文出自 “sunfish 翻车鱼” 博客,请务必保留此出处http://sunfish.blog.51cto.com/417500/113108
发表评论
-
servletcontext 的获取
2013-05-12 20:10 480容器在初始化servlet时,会为其注入servletconf ... -
取得下一个sequence。 getNextInterval
2013-03-15 11:47 9431. 初始sequence值放置于数据库。 2. 启动时产 ... -
java 脚本,编译与注解处理
2013-02-05 10:04 8571.java中支持脚本调用 通过脚本引擎来执行。 Obj ... -
java 安全管理器
2013-02-04 11:24 8351.在java语言实现中,扩展和系统加载器都是java实现的, ... -
RMI 底层实现
2013-01-28 16:43 9181. server端代码: Registry regist ... -
Java获取当前路径
2013-01-22 18:12 899无论是抽象路径名还是路径名字符串,都可以是绝对 路径名或相对 ... -
java1.5 新特性
2013-01-10 16:50 768"JDK1.5"的一个重要主题就是通过新增 ... -
import static静态导入
2013-01-10 12:12 850import static静态导入是JDK1.5中的新特性。一 ... -
类加载器加载的类的访问权限问题
2013-01-04 15:34 10591.父加载器加载的类不能访问子加载器加载的类。 (向下可见性) ... -
java 内部类总结
2012-12-28 12:31 748主要从分类和使用情境来看 1. 普通内部类。 位置: 在 ... -
java构造函数和静态变量的执行顺序
2012-12-18 11:18 1042java初始化顺序 1在new B一个实例时首先要进行类的装载 ... -
Java多线程之Condition接口的实现
2012-11-26 17:03 950在实际中一个lock可产生多个Condition对象。个人认为 ... -
java线程同步原理(lock,synchronized)
2012-11-26 14:26 1002一。 java线程同步原理 java会为每个object对象分 ... -
总结下java中abstract,interface,final,static,加深理解
2012-11-16 17:16 893一,抽象类:abstract 1,只要有一个或一个 ... -
为什么interface的变量必须是public final static的
2012-11-16 17:15 1019public 感觉是因为Java对接口的要求是所有类都可以实现 ... -
stack在排序的应用
2012-10-22 17:04 726对于list, 可用Collections的静态方法 Coll ... -
随机访问文件RandomAccessFile 与 内存映射文件MappedByteBuffer
2012-09-25 14:59 1579RandomAccessFile RandomAccessF ... -
Java 服务器端支持断点续传的源代码
2012-09-25 14:44 4043Java 服务器端支持断点续传的源代码【支持快车、迅雷】(仅支 ... -
new File(String parent,String child)
2012-08-22 23:00 1176//user_dir:E:\workspace\javates ... -
System.getProperty
2012-08-22 22:07 916System.getProperty(String name) ...
相关推荐
String 在 Java 中使用过于频繁,为了避免在系统中产生大量的 String 对象,Java 的设计者引入了“字符串常量池”的概念。当使用双引号创建一个字符串时,首先会检查字符串常量池中是否有相同的字符串对象,如果有,...
在JAVA学习过程中,初学者总是会遇到一些很疑惑的问题,往往是知其然不知其所以然。下面针对这些基础的问题进行一个详细的解答,以便后来者少走弯路,知其然知其所以然。 问题一:String 声明和引用 JAVA 语言中,...
当创建新的字符串对象时,如果该字符串在常量池中已经存在,则返回已存在的字符串引用;如果不存在,则将其放入常量池,并返回新创建的字符串引用。 **子串截取陷阱:** `String`类的`substring()`方法可能会导致...
例如,通过`new String("hello")`创建一个String对象,此时变量`str1`的类型是`object`,而直接赋值的字符串`str2`类型则是`string`。这样的区别在处理方法调用时尤其需要注意,因为对象方法和原始值方法的行为可能...
在Java中,局部变量(在方法内部声明的变量)存储在堆栈中,而对象引用和实例变量存储在堆内存中。堆栈内存管理快速高效,适用于生命周期短、创建和销毁频繁的变量。例如,当一个方法被调用时,一个新的堆栈帧会被...
在Java编程语言中,有很多细节和特性可能会让初学者感到困惑。本文将深入探讨几个常见的问题,以帮助初学者更好地理解和使用Java。 1. **内存管理与垃圾回收**:Java引入了自动内存管理机制,即垃圾回收(Garbage ...
学习过程中,作者特别标记了一些重难点问题,这将有助于读者在实践中解决常见的编程疑惑。总的来说,这是一个适合初学者的全面而系统的C++入门教程,对于想要踏入C++编程世界的人来说,是一份宝贵的资源。
虽然`a`和`b`都指向了内容为"foo"的字符串对象,但由于它们是由不同的`new String()`语句创建的,所以它们实际上位于内存的不同位置。因此,使用`==`进行比较返回`false`;而使用`equals()`则会比较字符串的内容,...
在Python中,所有变量都被视为内存中对象的“引用”。这一点非常重要,因为理解这一点有助于我们掌握Python中的参数传递机制。 - **不可更改对象**(Immutable Objects): 在Python中,字符串(string)、元组...
13. **标准库API**:对Java标准库中的常用类和方法的理解和应用,如String、Date、Calendar等。 备考SCJP 310-065时,考生需要通过题库进行反复练习,理解和掌握这些知识点。提供的两个文件"310-065.exe"和...
此外,实验中提到在使用类和主函数调用时存在疑惑。这通常涉及到类的对象实例化、成员函数调用的语法,以及如何正确地传递和管理数据。解决这类问题的最佳方法是多阅读相关教材,理解C++的面向对象编程基础,同时多...
**:在数据库索引中,一级索引通常指向具体的记录位置或扇区,具体实现取决于索引的设计和存储系统的特性。 - **B树/B+树为什么那样定义?**:B树和B+树的设计目的是为了提高数据访问速度,尤其是在磁盘等慢速存储...
同时,解答疑惑的部分将帮助他们解决学习过程中遇到的具体问题,加速他们的学习进度。在学习过程中,不断实践和总结是掌握任何编程语言的关键,"java解惑"提供的资源无疑是这样的一个实践和学习的优秀工具。
根据提供的标题“C++程序设计语言题解”和描述“C++程序设计语言题解,解决更多的疑惑”,我们可以推断出这份资料主要聚焦于解答与C++编程相关的各种问题和练习题。C++是一种广泛使用的面向对象的编程语言,由Bjarne...
*2.5 在C语言中是否有模拟继承等面向对象程序设计特性的好方法? 22 2.6 为什么声明extern f(struct x *p); 给我报了一个晦涩难懂的警告信息? 23 2.7 我遇到这样声明结构的代码:struct name {int namelen; ...
《C++ Primer Plus》第四版是一本广受欢迎的C++编程教材,旨在帮助读者深入理解和掌握C++语言。书中的代码示例和习题是学习过程中不可或缺的...在实践中遇到问题时,别忘了查阅书籍或在线资源,以加深理解和解决疑惑。
《JAVA解惑》是一本专为Java初学者和开发者设计的电子书,旨在解决他们在学习和实践Java过程中遇到的各种疑惑。这本书深入浅出地讲解了Java编程语言的关键概念和技术,帮助读者建立扎实的基础,并提升解决问题的能力...
6. **垃圾回收**:Lua自动管理内存,使用引用计数和弱引用策略回收不再使用的对象。 ### 四、 Lua 在游戏开发中的应用 1. **逻辑控制**:Lua脚本可以编写游戏逻辑,如角色行为、事件响应等,便于游戏逻辑的调试和...
同时,对于C语言的函数,如stdio、stdlib、string等头文件中的函数,也有详尽的解释和示例。 Java是一种跨平台的面向对象编程语言,它的标准类库JDK(Java Development Kit)提供了丰富的API,包括I/O流、网络编程...
o 3.5 在 C 中是否有模拟继承等面向对象程序设计特性的好方法? o 3.6 我遇到这样声明结构的代码: struct name { int namelen; char namestr[1];}; 然后又使用一些内存分配技巧使 namestr 数组用起来好像有多个...