1. 首先String不属于8种基本数据类型,String是一个对象。
因为对象的默认值是null,所以String的默认值也是null;但它又是一种特殊的对象,有其它对象没有的一些特性。
2. new String()和new String(“”)都是申明一个新的空字符串,是空串不是null;
3. String str=”kvill”;
String str=new String (“kvill”);的区别:
在这里,我们不谈堆,也不谈栈,只先简单引入常量池这个简单的概念。
常量池(constant pool)指的是在编译期被确定,并被保存在已编译的.class文件中的一些数据。它包括了关于类、方法、接口等中的常量,也包括字符串常量。
看例1:
String s0=”kvill”;
String s1=”kvill”;
String s2=”kv” + “ill”;
System.out.println( s0==s1 );
System.out.println( s0==s2 );
结果为:
true
true
首先,我们要知道Java会确保一个字符串常量只有一个拷贝。
因为例子中的s0和s1中的”kvill”都是字符串常量,它们在编译期就被确定了,所以s0==s1为true;而”kv”和”ill”也都是字符串常量,当一个字符串由多个字符串常量连接而成时,它自己肯定也是字符串常量,所以s2也同样在编译期就被解析为一个字符串常量,所以s2也是常量池中”kvill”的一个引用。
所以我们得出s0==s1==s2;
用new String() 创建的字符串不是常量,不能在编译期就确定,所以new String() 创建的字符串不放入常量池中,它们有自己的地址空间。
看例2:
String s0=”kvill”;
String s1=new String(”kvill”);
String s2=”kv” + new String(“ill”);
System.out.println( s0==s1 );
System.out.println( s0==s2 );
System.out.println( s1==s2 );
结果为:
false
false
false
例2中s0还是常量池中”kvill”的应用,s1因为无法在编译期确定,所以是运行时创建的新对象”kvill”的引用,s2因为有后半部分new String(“ill”)所以也无法在编译期确定,所以也是一个新创建对象”kvill”的应用;明白了这些也就知道为何得出此结果了。
4. String.intern():
再补充介绍一点:存在于.class文件中的常量池,在运行期被JVM装载,并且可以扩充。String的intern()方法就是扩充常量池的一个方法;当一个String实例str调用intern()方法时,Java查找常量池中是否有相同Unicode的字符串常量,如果有,则返回其的引用,如果没有,则在常量池中增加一个Unicode等于str的字符串并返回它的引用;看例3就清楚了
例3:
String s0= “kvill”;
String s1=new String(”kvill”);
String s2=new String(“kvill”);
System.out.println( s0==s1 );
System.out.println( “**********” );
s1.intern();
s2=s2.intern(); //把常量池中“kvill”的引用赋给s2
System.out.println( s0==s1);
System.out.println( s0==s1.intern() );
System.out.println( s0==s2 );
结果为:
false
**********
false //虽然执行了s1.intern(),但它的返回值没有赋给s1
true //说明s1.intern()返回的是常量池中”kvill”的引用
true
最后我再破除一个错误的理解:
有人说,“使用String.intern()方法则可以将一个String类的保存到一个全局String表中,如果具有相同值的Unicode字符串已经在这个表中,那么该方法返回表中已有字符串的地址,如果在表中没有相同值的字符串,则将自己的地址注册到表中“如果我把他说的这个全局的String表理解为常量池的话,他的最后一句话,“如果在表中没有相同值的字符串,则将自己的地址注册到表中”是错的:
看例4:
String s1=new String("kvill");
String s2=s1.intern();
System.out.println( s1==s1.intern() );
System.out.println( s1+" "+s2 );
System.out.println( s2==s1.intern() );
结果:
false
kvill kvill
true
在这个类中我们没有声名一个”kvill”常量,所以常量池中一开始是没有”kvill”的,当我们调用s1.intern()后就在常量池中新添加了一个”kvill”常量,原来的不在常量池中的”kvill”仍然存在,也就不是“将自己的地址注册到常量池中”了。
s1==s1.intern()为false说明原来的“kvill”仍然存在;
s2现在为常量池中“kvill”的地址,所以有s2==s1.intern()为true。
5. 关于equals()和==:
这个对于String简单来说就是比较两字符串的Unicode序列是否相当,如果相等返回true;而==是比较两字符串的地址是否相同,也就是是否是同一个字符串的引用。
6. 关于String是不可变的
这一说又要说很多,大家只要知道String的实例一旦生成就不会再改变了,比如说:String str=”kv”+”ill”+” “+”ans”;
就是有4个字符串常量,首先”kv”和”ill”生成了”kvill”存在内存中,然后”kvill”又和” “ 生成 ”kvill “存在内存中,最后又和生成了”kvill ans”;并把这个字符串的地址赋给了str,就是因为String的“不可变”产生了很多临时变量,这也就是为什么建议用StringBuffer的原因了,因为StringBuffer是可改变的
分享到:
相关推荐
Java中的String对象是一种特殊的数据类型,它有其它对象没有的一些特性。String对象可以通过两种方式创建,常量池中的字符串常量和运行时创建的新对象。String.intern()方法可以将一个String对象添加到常量池中,并...
### Java String对象的经典问题 #### 一、String 类与对象机制概述 在Java中,`String`类是一个非常重要的类,它提供了丰富的功能用于处理文本数据。`String`类是不可变的(immutable),这意味着一旦一个`String`...
"Java中String的特性" Java中String的特性是一种非可变类,它的创建方式有两种:使用new关键字和使用字面量。使用new关键字创建的...这种特性使得Java中的String对象可以被多个引用共用一个对象,而不会互相影响。
本文将详细探讨 Java 中 String 类的特性及其使用。 Java 中的 String 类提供了丰富的方法和特性,使得字符串的操作变得简单而强大。不可变性、字符串常量池、以及各种字符串操作方法都是 String 类的关键特性。通过...
标题和描述均强调了在Java中处理`String`对象时可能遇到的陷阱,尤其是在理解和使用`String`的处理机制上。文章由天津工业大学软件工程专业的翁龙辉撰写,旨在深入剖析`String`在Java中的独特行为及其潜在的陷阱。...
总结来说,Java中的String对象的不可变性是其核心特性和优势,但同时也需要开发者在处理字符串操作时,根据具体需求选择合适的方法。理解这一概念有助于写出更高效、安全和易于维护的Java代码。
深入了解Java中的String类是至关重要的,因为String在Java编程中占据着极其重要的位置。下面将对给定的信息进行深入分析: ### 1. String 类是 final 的,不可被继承 在Java中,`String` 类被声明为 `final` 类型...
这一特性对于Java内存管理有着重要影响,因为String对象会存储在方法区的字符串常量池中,以避免重复创建相同的字符串,从而提高内存使用效率。 在JDK 8版本中,字符串常量池的位置发生了变化,从方法区移至Java堆...
` 这种方式创建的String对象是在常量池中,如果已有相同内容的字符串,那么会复用已存在的对象。 - 使用`new`关键字:`String userName = new String("Eric");` 这种方式会在堆内存中创建一个新的对象,即使字符串...
- String对象在Java中是通过引用常量池中的常量来创建的,一旦创建就不能改变。例如,`String str = "Hello"` 创建了一个字符串对象。 - 因为不可变性,每次对字符串进行修改(如使用`concat()`或`substring()`)...
在Java中,面向对象特性主要包括封装、继承和多态。 1. 封装:封装是面向对象编程的基础,它将数据和操作数据的方法捆绑在一起,隐藏内部实现细节。在Java中,我们通过定义类来实现封装。类是一个模板或蓝图,用于...
### Java中String类详解 #### 引言 在Java编程语言中,`String`类扮演着至关重要的角色,它用于表示字符序列。本文档旨在深入探讨`String`类的特性和功能,帮助开发者更好地理解和应用这一核心类。 #### String类...
**创建String对象的方式:** 1. **直接赋值法:** ```java String str1 = "otherwords"; ``` 这种方式创建的字符串会直接放在常量池中,如果第二次出现相同的字符串,那么它会直接指向常量池中的已有对象。 2....
这是因为`String`在Java中被实现为一个特殊的类,存储在一个连续的字符数组中,这个特性对于理解它的内部工作原理以及如何有效地使用它至关重要。下面将详细探讨`String`类的数据结构、常用方法以及适用于初学者的...
内存管理方面,Java中的`String`对象存储在堆内存中,并且可以存在常量池。如果创建的`String`值相同,它们可能引用同一个对象。例如: ```java String s1 = "abc"; String s2 = "abc"; System.out.println(s1 == s2...
本课件主要探讨了Java的面向对象特性,包括类、对象、抽象类和接口、内部类等概念。 首先,面向对象程序设计(OOP)是基于抽象数据类型、类和对象、封装、继承和多态性等概念的。抽象数据类型是一种数据结构的定义...
Java语言是一种广泛使用的编程语言,尤其以其强大的面向对象特性而闻名。面向对象编程(Object-Oriented Programming,简称OOP)是Java的核心理念,它基于类和对象的概念,旨在提高代码的可重用性、可维护性和模块化...
与此相关的,`String`对象是Java编程语言中的基础类型,用于存储和处理文本数据。在实际开发中,我们经常需要在`String`对象与JSON对象之间进行转换,以满足不同的需求。本文将深入探讨`String`与JSON的互转方法,并...
### 深层解析Java虚拟机中的栈与堆:对象的内存分布 #### 核心概念:栈与堆的本质及作用 在Java编程语言中,理解栈(stack)和堆(heap)的概念及其工作原理对于深入掌握Java虚拟机(JVM)如何管理内存至关重要。栈和堆...
9. `public String toString()`:返回字符串本身,因为String对象已经是一个字符串。 10. `public String toUpperCase()`:将字符串中的所有小写字母转换为大写字母。 11. `public String trim()`:去除字符串两端的...