关于String面试中的知识点

String面试题与知识点

1.本篇文章主要讲解关于string的知识点,通过部分的面试题来展示具体的String考点,也是对自己最近学习的一个总结。

不可变类

String 是不可变类,一个对象被创建出来,它的值就不变了
看下面的代码

public class Test
{
public static void main(String[] args){
String s ="Hello";
s+="world";
System.out.println(s);
 } 
}

为什么不变类最后的值变了呢?

String s =“hello” 声明了一个可以指向String 类型对象的引用
当执行了s+=“world” s指向了另一个对象,那个hello依然在内存中。

如何实现一个不变类

不变类有5条基本原则
(1)类中所有的成员变类被private所修饰

(2)类中没有写或者修改成员变量的方法,只提供构造函数,一次生成,永不改变

(3)确保类中所有方法不会被子类覆盖,可以通过定义final来实现

(4)如果一个类成员不是不可变量,那么在成员初始化或者get时需要使用clone();

(5)如果有必要,可以通过覆盖Object类的equals()方法和hashcode()方法,来比较两个对象能否正常放到HashMp中

写一个不变类时在创建对象的时候就要初始化所有的成员变量

这里补充一些:
对于一些敏感的数据,要使用字符数组存储, 比String更安全。

String是不变类,它被存储在常量字符串池中,实现字符串的共享,减少内存的开支,一个String类型的字符串创建出来,这个字符串就存在于常量池中,直到垃圾回收器回收,但是这些数据在未被回收之前是可以被访问到的,所以容易出现安全隐患。

String 在内存中的操作

上面讲到了String存储在字符串常量池中,那下来就整理一下关于jvm里的东西,jvm主要分为5部分:
jvm在1.6 1.7 和1.8对于字符串常量池的位置发生了变化,
可以在这篇博客去看一下不同的内存模型
链接: 博客地址.
这是一张jdk1.8的jvm内存模型

在这里插入图片描述
(来自网络)
jvm大致有4个主要的子系统
类装载子系统:把class文件加载到内存中,供虚拟机执行
垃圾回收器 (GC) 垃圾回收机制
**执行引擎:**负责执行字节码
运行时数据区 :java内存,整个计算机中划分一块内存区域中存储许多东西

大致讲一下运行时数据区的五个逻辑区域:
1.·程序计数器
给每个线程执行一个单独的程序计数器,通过改变这个计数器的值来确定下一个要执行的字节码指令。
2.本地方法栈
当执行的方法是native时,native方法接口都会使用某种本地的方法栈
3.堆 所有线程共享的区域,区域主要是用来存放对象的实例,通过new操作创建的对象放到这个堆空间中。
4.java虚拟机栈 线程是有的区域,这个栈主要是实现java语言中的方法调用和执行,主要的操作是入栈和出栈。

5.方法区: 类加载的类信息,常量和静态变量,编译后的代码放入这个方法区中。

1.6 中StringTable 在永久代中存放,StringTable也就是字符串常量

1.7中 将字符串常量池和静态变量放入了堆中,但一些基本的还是用的虚拟机内存,还是相当于在方法区中。

1.8中:将方法区的概念彻底去了,换成了元空间,而静态常量和字符串常量池依旧留在了堆中,运行时常量池随着元空间放到了本地内存中。

说到原因就是
1.静态常量和字符串常量实在常用,使用频率高,放在老年代垃圾回收效率太低。
2.将方法区放入元空间主要就是永久代大小难以确定。
调优困难

==和.equals 与hashcode

(1)“==” 用来比较两个变量的值是否相等,比较内存中存储的数值是否相同
如果比较对象是基本类型,直接= = 比较对应的值是否相等,
如果说变量指的是对象,这时设计到了两块内存,一块是对象的内存在堆中,变量的值也占用一块内存
比如 String s = new String();
s占用一块内存,new String()也占用一块内存。
s对应存储的就是对象占用内存的首地址,
如果此时比较两个变量是否指向同一个对象
如果要看这两个变量对应的内存中的数值是否相同,无法用= = 实现
(2)equals() 是object类提供的方法之一 ,因为每个java类都继承object类,euqals方法可以被覆盖,
在没有覆盖的情况下,equals() 和= = 是一样的,比较的引用。
String s1 = new String(“Hello”);
String s2 =new Stirng(“Hello”);

new 创建了两个对象,然后使用s1,s2指向一个对象,他们的首地址不同
但是String 重写了equals()方法,比较的是他们的值。

hashcode也是从equals中继承过来的方法,鉴定两个对象是否相等
hashcode()返回对象在内存中地址转换为一个int值,如果没有重写hashcode() 任何对象的hashcode()方法都是不同的。
一般重写equals()时 hashcode也要重写,不然会导致hashmap等的使用错误。

String的intern()方法

当intern()方法被调用,如果字符串池中含有一个字符串和当前调用方法的字符串eqauls相等,那么就会返回池中的字符串。如果池中没有的话,则首先将当前字符串加入到池中,然后返回引用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值