基础知识——关于String

String对象的两种创建方式

?
?

关于String有很多问题,首先关于String的创建,有两种创建方式

?
?

String x = "abc";

String z = new String("abc");

?
?

那么这两种方式有什么不同呢

?
?

两者的不同

?
?

其实这两种方式创建的"abc"并不在一个地方,第一句的真正含义是在String池中创建一个对象"abc",然后在栈内创建一个引用x指向池中的对象"abc";第二句实在堆中创建一个对象"abc",然后在栈内创建一个引用z指向堆中的对象"abc"

?
?

首先我们都知道Java中有堆和栈两个重要的内存区域,栈里面放着基本数据类型和对象的引用,而堆里面放着实实在在的对象,由new操作创建的对象肯定是放在堆里的,但是由双引号创建的对象则是放在String池里的,这个String池是常量池的一部分,它不属于堆和栈,它属于方法区(其实Java内存区域除了堆,栈之外还有程序计数器,本地方法栈,方法区这几部分)

?
?

双引号创建方式

?
?

双引号创建方式创建的内容相同的字符串是同一个字符串

?
?

String x = "abc";

String y = "abc";

?
?

Java虚拟机在运行时维护一个String池,池中的String对象是单例的,首先String x = "abc"想创建字符串对象"abc"的时候首先会查看字符串池中是否已经存在,存在就直接返回池中的该String对象,这里不存在,那么就会创建一个新的String对象,并将该对象放进字符串池中,然后再栈中创建引用x,指向它

?
?

在String y = "abc"想创建字符串对象"abc"的时候它首先也会查看字符串池中是否已经存在,由于已经存在,那么就直接返回池中的该String对象,然后再栈中创建引用y,指向它,由于是已经存在的,所以它们俩指向的是同一个对象

?
?

字符串常量池的作用

?
?

字符串池是为了解决字符串重复的问题,生命周期长,它存在于 permgen 中。而且放入字符串常量池实在编译的时候完成的,源文件中出现的双引号内的字符串都被收纳到常量池中。

?
?

几个测试

?
?

有了之前的知识基础我们看看常见的一些测试

?
?

首先x==y肯定是对的

然后x=="abc"肯定也是对的,这里的"abc"也在常量池中

然后z=="abc"是不对的,因为"abc"在常量池中,z在堆中,==判断的是地址

然后x.equals(z)这个是对的,因为String重写了equal方法,会去判断字符串的内容是否相等

但是x==z就是不对的

?
?

String的intern方法

?
?

下面说一下intern()方法,该方法先在String池中查找是否存在一个对象,存在了就返回String池中对象的引用,如果不存在就在池中创建该对象。

那么这样说起来,本来x==z是不对的,但是x==z.intern()就是对的,大家可以测试一下

?
?

String的hashCode方法

?
?

下面再说一下hashCode()方法,这个方法是返回字符串内容的哈希码,那么这样说来,虽然x==z是错的,但x.hashCode==z.hashCode就是对的,因为hashCode是根据字符串内容算出来的,既然内容相同,哈希码必然相同

?
?

String的连接

?
?

String重载了+运算符用于实现字符串的连接,但是由于String是不可更改的,所以+其实是新创建了一个字符串对象

?
?

由于使用+连接字符串每次都生成新的对象,而且是在堆内存上进行,而堆内存速度比较慢(相对而言),那么大量连接字符串时使用+的效率就会比较低。Java提供了StringBuffer和StringBuilder来解决这个问题。

?
?

区别是前者是线程安全的而后者是非线程安全的,StringBuilder在JDK1.5之后才有。不保证安全的StringBuilder有比StringBuffer更高的效率。

?
?

另外有种说法是JDK1.5之后,Java虚拟机执行字符串的+操作时,内部实现也是StringBuilder,之前采用StringBuffer实现,但是每次相加后其实还是都在堆区再新创建了一个对象,只是省去了中间大量连续连接字符串所创建的消耗

时间: 2024-10-13 06:51:24

基础知识——关于String的相关文章

JS基础知识梳理---String对象

A:对象的声明 var stringObject = new String(“hello word”); var stringObjectB = “hello word”; B:StringObject具备的属性 StringObject.length,字符串长度(空格也占位);相应的,可以通过string[n]来访问字符串中角标为n的字符 var str = “today is good today”; console.log(str.length);//19 console.log(str[

Java中String的基础知识

Java中String的基础知识 ==与equal的区别 基本数据类型,指的是java中的八种基本数据结构(byte,short,char,int,long,float,double,boolean),一般的比较是使用的 ==,比较的是他们的值. 复合数据类型(类) ==比较的是两个对象的引用,可以理解为在内存中的地址,除非是同一个new出来的对象,他们的 ==为true,否则,都为false. equal是object中的方法.object中的实现如下,内部还是使用==实现,也就是说,如果一个

java基础知识回顾之---java String final类普通方法

辞职了,最近一段时间在找工作,把在大二的时候学习java基础知识回顾下,拿出来跟大家分享,如果有问题,欢迎大家的指正. /*     * 按照面向对象的思想对字符串进行功能分类.     *      *      * 1,获取:     * 1.1 获取字符串中字符的个数(长度).     *         int length();     * 1.2 取字符串中的某一个字符,其中的参数index指的是字符串中序数.字符串的序数从0开始到length()-1 .     *       

C#语言基础知识(4):C#中的String.Format方法

定义String.Format是将指定的String类型的数据中的每个格式项替换为相应对象的值的文本等效项.(1)string p1="xiaomeng";string p2="xiaobei";Response.Write(String.Format("Hello {0},I'm {1}",p1,p1));(2)Response.Write(String.Format("Hello {0},I'm {1}","xi

java基础知识回顾之---java String final类之intern方法

public class StringObjectDemo { /** * @param args */ public static void main(String[] args) { String hello = "Hello", lo = "lo"; System.out.print((hello == "Hello") + " ");//true System.out.print((Other.hello == hel

php基础知识总结(3)字符串函数string

一.大小写转换 1.strtolower()--转换为小写. echo strtolower("Hello WORLD!"); //hello world! 2.strtoupper()--转换为大写. echo strtoupper("Hello WORLD!"); //HELLO WORLD! 3.ucfirst()--把首字母转换为大写. echo ucfirst("hello world");     //Hello world 4.uc

java基础知识回顾之---java String final类普通方法的应用之“按照字节截取字符串”

/*需求:在java中,字符串“abcd”与字符串“ab你好”的长度是一样,都是四个字符.但对应的字节数不同,一个汉字占两个字节.定义一个方法,按照最大的字节数来取子串.如:对于“ab你好”,如果取三个字节,那么子串就是ab与“你”字的半个,那么半个就要舍弃.如果去四个字节就是“ab你”,取五个字节还是“ab你”.*/ 代码:其实是一个解码和编码的问题,要明白UTF-8码表和GBK码表的区别,UTF-8中用三个字节代表一个汉字,GBK使用2个字节代表一个汉字. 且在码表中都是用数字存放这些汉字.

java基础知识回顾之---java String final类 容易混淆的java String常量池内存分析

/** *   栈(Stack) :存放基本类型的变量数据和对象的引用,但对象本身不存放在栈中,而是存放在堆(new 出来的对象)或者常量池中(字符串常量对象存放  在常量池中). 堆(heap):存放所有new出来的对象. *   静态存储:存放静态成员(static定义的). 常量池(constant pool):在堆中分配出来的一块存储区域,存放储显式的String常量和基本类型常量(float.int等).另外,可以存储不经常改变的东西 *                       p

C++ 基础知识回顾(string基础、智能指针、迭代器、容器类)

[1] string基础 [1.1] string 的构造 1 #include <iostream> 2 #include <string> 3 4 int main() 5 { 6 using namespace std; 7 8 cout << "1 --- string(const char* s):将string对象初始化为s指向的C风格字符串" << endl; 9 string one("benxintuzi_1&