String字符串的介绍:
String属于引用数据类型,由于被final修饰,所以String是不可变的,JVM使用字符串池来存储所有的字符串对象。
1、字节和字符的区别?
答:
字节是存储容量的基本单位;
字符是数字、字⺟、汉字以及其他语⾔的各种符号;
1 字节 = 8 个⼆进制单位,⼀个字符由⼀个字节或多个字节的⼆进制单位组成。
——————————————————————————————————
2、java中String为什么要设计为不可变类?
答:
C++中string是可变类,可以对string进行一些增删改查的操作,但是在 Java 中将 String 设计成不可变的是综合考虑到各种因素的结果。主要的原因主要有以下三点:
(1)字符串常量池的需要:字符串常量池是 Java 堆内存中⼀个特殊的存储区域, 当创建⼀个 String 对象时,假如
此字符串值已经存在于常量池中,则不会创建⼀个新的对象,⽽是引⽤已经存在的对象;
(2)允许 String 对象缓存 HashCode:Java 中 String 对象的哈希码被频繁地使⽤, ⽐如在 HashMap 等容器中。
字符串不变性保证了 hash 码的唯⼀性,因此可以放⼼地进⾏缓存。这也是⼀种性能优化⼿段,意味着不必每次都
去计算新的哈希码;
(3)String 被许多的 Java 类(库)⽤来当做参数,例如:⽹络连接地址 URL、⽂件路径 path、还有反射机制所需要
的 String 参数等, 假若 String 不是固定不变的,将会引起各种安全隐患。
———————————————————————————————————
3、String、StringBuilder、StringBuffer 的区别?
答:
String:⽤于字符串操作,属于不可变类;【补充:String 不是基本数据类型,是引⽤类型,底层⽤ char 数组实现
的】
StringBuilder:与 StringBuffer 类似,都是字符串缓冲区,但线程不安全;
StringBuffer:也⽤于字符串操作,不同之处是 StringBuffer 属于可变类,对⽅法加了同步锁,线程安全。
————————————————————————————————————
4、String字符串修改实现的原理?
答:
当⽤ String 类型来对字符串进⾏修改时,其实现⽅法是⾸先创建⼀个 StringBuffer,其次调⽤ StringBuffer 的
append() ⽅法,最后调⽤ StringBuffer 的 toString() ⽅法把结果返回。apend()是添加方法。
——————————————————————————————————————
5、String str = “i” 与 String str = new String(“i”) ⼀样吗?
答:
不⼀样,因为内存的分配⽅式不⼀样。String str = “i” 的⽅式,Java 虚拟机会将其分配到常量池中;⽽ String str =
new String(“i”) 则会被分到堆内存中。
在执⾏ String str1 = “abc” 的时候,JVM 会⾸先检查字符串常量池中是否已经存在该字符串对象,如果已经存在,
那么就不会再创建了,直接返回该字符串在字符串常量池中的内存地址;如果该字符串还不存在字符串常量池中,
那么就会在字符串常量池中创建该字符串对象,然后再返回。所以在执⾏ String str2 = “abc” 的时候,因为字符串
常量池中已经存在“abc”字符串对象了,就不会在字符串常量池中再次创建了,所以栈内存中 str1 和 str2 的内存地
址都是指向 “abc” 在字符串常量池中的位置,所以 str1 = str2 的运⾏结果为 true。
⽽在执⾏ String str3 = new String(“abc”) 的时候,JVM 会⾸先检查字符串常量池中是否已经存在“abc”字符串,如
果已经存在,则不会在字符串常量池中再创建了;如果不存在,则就会在字符串常量池中创建 “abc” 字符串对象,
然后再到堆内存中再创建⼀份字符串对象,把字符串常量池中的 “abc” 字符串内容拷⻉到内存中的字符串对象中,
然后返回堆内存中该字符串的内存地址,即栈内存中存储的地址是堆内存中对象的内存地址。String str4 = new
String(“abc”) 是在堆内存中⼜创建了⼀个对象,所以 str 3 == str4 运⾏的结果是 false。str1、str2、str3、str4 在
内存中的存储状况如下图所示:
——————————————————————————————————————
6、String类常用的方法都有哪些?
答:
——————————————————————————————————
7、如何将String转换为char?反过来呢?
答:
String是一系列字符,在java中是不可变的类型,但是其底层原理仍然是用了char字符。所以我们无法转换成单一的char但是可以调用toCharArray()方法将字符串转换成字符数组。
——————————————————————————————————————
8、写一个方法用来判断一个String字符串是否是回文串?
答:
——
——————————————————————————————————
9、什么是字符串池?
答:
字符串常量池就是用来存储字符串的,它存在于java对内存中。
下图解释了字符串池在java堆空间中如何存在以及当我们使用不用方式创建字符串时情况。
——————————————————————————————————————
10、String是线程安全的吗?
答:
String是不可变量,一旦创建了String对象,我们就无法改变他的值,因此,它的线程是安全的,可以安全的用于多线程环境中。
————————————————————————————————————————
11、为什么我们在使用HashMap的时候总是用String做key?
答:
因为字符串是不可变的,当创建字符串的时候,他的hashcode被缓存下来,不需要再次计算。因为HashMap内部实现是通过key的hashcode来确定value的存储位置,所以相比于其他对象更快。这也就是为什么我们平时使用String作为HashMatp对象。
—————————————————————————————————————————
12、
————————————————————————————————————
13、了解String.intern()方法吗?
答:
String.intern()查找常量池中是否有相同的unicode字符串常量,如果有则返回其引用,如果没有,则在常量池中增加一个unicode等于str的字符串并返回它的引用。因此在用String进行字符串拼接时,会产生很多临时变量。建议多使StringBuffer/StringBuilder。
————————————————————————————————————
14、、String/StringBuffer/StringBuilder都分别存放在什么地方?
答:
String是存放在常量池中,在编译期间已经被确定了。new String()不是字符串常量,他有自己的地址空间,放在堆空间,而其他两个都存放在堆空间中。
————————————————————————————————————————
15、new String(“abc”)和string str="abc"的区别
答:
new出来的对象是先在常量池看是否有这个字符串内容,如果有直接在堆里面创建一个对象,存储这个字符串在常量池的地址,如果没有要先在常量池创建一个内存,存储这个字符串,然后再将这个地址存在内存中
——————————————————————————————————————————
16、String str = new String(“Cat”);这句话创建了几个对象?
答:
一个或者两个
原因:先判断字符串常量池里面有没有Cat字符串对象,如果有,就不会在常量池里面创建Cat对象,但是会在堆内存里面创建一个Cat对象,并将对象地址返回给str变量,这种情况创建一个对象;
如果常量字符串没有,就会现在常量池里面创建Cat字符串,然后再在堆内存里面创建Cat字符串对象,这种情况会创建两个对象
——————————————————————————————————————————
17、 说一下以下代码输出结果
答: