String字符串的存储原理

  • 关于java 的jdk中内置的一个类:java.lang.String
  • String表示字符串类型,属于引用数据类型,不属于基本数据类型
  • 在java中随便使用双引号括起来的都是String对象
  • java中规定,双引号括起来的字符串,是不可变的,也就是说“abc”自出生到最终死亡,不可变,不能变成“abcd",也不能变成”ab"
  • 在JDK当中双引号括起来的字符串,例如:“abc","def"都是直接存储在方法区的字符常量池当中的
  • 垃圾回收器是不会释放常量的
  • 为什么sun公司把字符串存储在一个”字符串常量池“当中呢。因为字符串在实际开发中使用太频繁,为了执行效率,所以把字符串放到了方法区的字符串常量池当中。
  • 关于String类中的构造方法
  • 第一个:String s= new String("")
  • 第二个:String s=""; 最常用
  • 第三个:String s= new String(char 数组);
  • 第四个:Sting s=new String(char数组,起始下标,长度):
  • 第五个:String s= new String(byte 数组);
  • 第六个:Sting s=new String(byte数组,起始下标,长度):
  • 一些常用的方法:
  • contains
  • equals
  • 比较两个字符串必须使用equals方法,不能使用“==”
  • compareTo
  • endsWith
  • equalsIgnoreCase
  • 判断两个字符串是否相等,并且同时忽略大小写
  • indexOf
  • 判断某个子字符串在当前字符串中第一次出现处的索引
  • lastIndexOf
  • 判断某个子字符串在当前字符串中最后一次出现处的索引
  • isEmpty
  • 判断某个字符串是否为空
  • 面试题:判断数组长度和判断字符串长度不一样
  • 判断数组长度是length属性,判断字符串长度是length()方法
  • replace
  • 使用指定的字面值替换序列 替换此字符串所有匹配字面值目标序列的子字符串
  • lastIndexOf
  • 判断某个子字符串在当前字符串中最后一次出现的索引(下标)
  • startsWidth
  • 判断某个字符串是否以某个子字符串开始、
  • endsWith
    -
    subString
  • 截取字符串
  • toLowerCase
  • 转小写
  • toUpperCase
  • 转大写
  • trim
  • 去除字符串首尾的空白
  • String中只有一个方法是静态的,不需要new对象,这个方法叫valueOf。作用是将非字符串转换成字符串
  • 在实际开发中,如果需要进行字符串的频繁拼接,会有什么问题?
  • 因为java中的字符串是不可变的,每一次拼接都会产生新字符串。这样会占用大量的方法区内存,造成内存空间的浪费。
    String s=“abs”;
    s+=“sdf”;
    以上代码,导致在方法区字符串常量池当中创建了3个对象。“abs" , “sdf”,“abssdf”
    如果以后需要进行大量字符串的拼接操作,建议使用JDK中自带的:
  • java.lang.StringBuffer
  • java.lang.StringBuilder
  • 两者的区别
  • StringBuffer中的方法都有:synchronized关键字修饰,表示StringBuffer在多线程环境下运行是安全的
  • StringBuilder:无synchronized关键字修饰,非线程是安全的
  • java中为8种基本数据类型又对应准备了8种包装类型。8种包装类型属于 引用数据类型,父类为object
  • 为什么提供包装类?
  • 因为8种基本数据类型不够用
  • 这种包装类在实际开发中,我们不需要自己写。8种基本数据类型对应的8种包装类,sun公司已经写好了。直接用。
  • 8种基本数据类型对应的包装类型名是什么?

基本数据类型

包装类型

byte

java.lang.Byte

short

java.lang.Short

int

java.lang.Integer

long

java.lang.Long

float

java.lang.Float

double

java.lang.Double

char

java.lang.Character

boolean

java.lang.Boolean

  • 8种包装类中其中6个都是数字对应的包装类,他们的父类都是number,可以县研究一下number中公共的方法:
  • number是抽象类,无法实例化对象
  • 基本数据类型-- 转换为 — 引用数据类型 叫做 装箱
  • 引用数据类型-- 转换为 — 基本数据类型 叫做 拆箱
  • 在jdk1.5之后,支持自动拆箱和自动装箱了
  • Integer的构造方法
  • 构造方法有两个
  • Integer(int)
  • Integer(String)
  • String为啥是不可变的
  • string类中有一个byte数组,并且这个byte数组是使用final修饰的。因为数组一旦创建,长度不可变,并且被final修饰的引用一旦指向某个对象之后,不可再指向其他对象,所以string是不可变的。
  • stringBuilder or stringBuffer 为什么是可变的
  • 这两内部实际上是一个byte[]数组,这个byte[]数组没有被final修饰。stringBuilder or stringBuffer的初始化容量我记得是16.当存满之后回进行扩容,底层调用数组拷贝的方法 system.arraycopy()…是这样扩容的。所以。。。