【校招VIP】Java中 String类的详解

08月04日 收藏 0 评论 0 java开发

【校招VIP】Java中 String类的详解

转载声明:文章来源:https://blog.csdn.net/lu202032/article/details/117047712

一、String类的使用:

String:字符串,使用一对“”引起来表示

String声明为final的,不可以被继承

字符串的字符使用Unicode进行编码,一个字符(不区分字母还是汉字)占两个字节

String实现了Serializable接口:表示字符串是支持序列化的,说明可以在网络上传输。

实现了Comparable接口:表示String可以比较大小

String类内部定义了final char[] value用于存储字符串数据

一定要注意:value是一个final类型,不可以修改:即value不能指向新的地址,但是单个字符内容是可以变化的。

String代表不可变的字符序列,简称:不可变性

体现:1.当对字符串重新赋值时,需要重新指定内存区域赋值,不能使用原有的value进行赋值。

2.当对现有的字符串进行连接操作时,也需要重新指定内存区域赋值,不能使用原有的value进行赋值。

3.当调用String的replace()方法修改指定字符或字符串时,也需要重新指定内存区域赋值,不能使用原有的value进行赋值。

通过字面量的方式(区别于new)给一个字符串赋值,此时的字符串值声明在字符串常量池中

字符串常量池中是不会存储相同内容的字符串的

案例代码如下:

package www.demo1;

import org.junit.Test;

public class StringTest {
@Test
public void test1(){
final char[] value = {'a', 'b', 'c'};
char[] v2 = {'t', '0', 'm'};
value[0] = 'H';
// value=v2; //不可以修改value地址

//"abc" 字符串常量,双引号括起的字符序列
String s1="abc"; //字面量的定义方式
String s2="abc";
//比较s1,s2的地址值,结果为true
System.out.println(s1==s2);
s1="hello";
System.out.println(s1);
System.out.println(s2);
System.out.println("***********************");


String s3="abc";
s3+="def";
System.out.println(s3);

System.out.println("***********************");
String s4="abc";
String s5=s4.replace("a","m");
System.out.println(s4);
System.out.println(s5);
}
}

二、String实例化的方式:

方式一:通过字面量定义的方式

方式二:通过new + 构造器() 的方式

代码理解:

//通过字面量定义的方式:此时数据abc声明在方法区中的字符串常量池中
String s1="abc";
String s2="abc";
//通过new+构造器的方式: 此时s3,s4保存的地址值,是数据在堆空间中开辟以后对应的地址值
String s3 = new String("abc");
String s4 = new String("abc");

System.out.println(s1==s2);//true
System.out.println(s1==s3);//false
System.out.println(s1==s4);//false
System.out.println(s3==s4);//false
System.out.println("**************************");
Person p1 = new Person("Tom",14);
Person p2 = new Person("Tom",14);
System.out.println(p1.name.equals(p2.name));//true,因为比较的是实体内容(String重写了equals()方法)
System.out.println(p1==p2);//false new的两个对象地址值是不一样的
System.out.println(p1.name==p2.name); //true
p1.name="Lay";
System.out.println(p2.name); //结果为Tom

结论:

常量与常量的拼接结果在常量池,且常量池中不会存在相同内容的常量

只要其中有一个结果是变量,结果就在堆中

如果拼接的结果调用intern()方法,返回值就在常量池中

加上代码便于理解:

String s1 = "Java";
String s2 = "Android";
String ss ="JavaAndroid";

String s3 = "Java"+"Android";
String s4 = s1 + "Android";
String s5 = "Java" + s2;
String s6 = s1 + s2;

System.out.println(ss==s3);//true
System.out.println(ss==s4); //false
System.out.println(ss==s5);//false
System.out.println(ss==s6);//false
System.out.println(s4==s5);//false

String s7=s4.intern();
System.out.println(ss==s7);//true

额外补充

创建String对象的两种方式:

String的内存布局:

String的相关测试

测试题1:

public class StringExercise01 {
public static void main(String[] args) {
String a = "abc";
String b = "abc";
//String重写了equals方法 ,比较的是具体的值,所以为true
System.out.println(a.equals(b)); //true

//a 首先看常量池有没有abc
//b 首先看常量池有没有abc 有,就将b直接指向abc
//所以地址值是一样的
System.out.println(a == b); //true
}
}

测试题2:

public class StringExercise02 {
public static void main(String[] args) {
String a = "ly";
String b = new String("ly");
System.out.println(a.equals(b)); //true
System.out.println(a == b); //false
System.out.println(a == b.intern()); //true
System.out.println(b == b.intern()); //false

//当调用intern()方法时,如果池已经包含一个等于此String对象的字符串(用equals(Object)方法确定)
//则返回池中的字符串.否则,将此String对象添加到池中,并返回此String对象的引用
//解读:b.intern() 方法最终返回的是常量池的地址(对象)
}
}

测试题3:

public class StringExercise03 {
public static void main(String[] args) {
String s1 = "ly"; //s1 指向常量池的ly
String s2 = "java"; //s2 指向常量池的java
String s4 = "java"; //s4 指向常量池的java
String s3 = new String("java"); //指向堆中的对象

System.out.println(s2 == s3); //false
System.out.println(s2 == s4); //true
System.out.println(s2.equals(s3)); //true
System.out.println(s1 == s2); //false
}
}

String类相关的面试题

面试题1:

//创建了几个对象? 只有1个对象
String a = "hello" + "abc";//等价于==>String a = "helloabc";
System.out.println(a);

面试题2:

public class StringExercise06 {
public static void main(String[] args) {
String s1 = "lyedu";//指向常量池中的"lyedu"
String s2 = "java";//指向常量池中的"java"
String s5 = "lyedujava"; //指向常量池中的"lyedujava"
String s6 = (s1 + s2).intern(); //指向池中的 "lyedujava"
System.out.println(s5 == s6); //true
System.out.println(s5.equals(s6)); //true
}
}

面试题3:

public class StringExercise07 {
public static void main(String[] args) {
Test1 ex = new Test1();
ex.change(ex.str, ex.ch);
System.out.println(ex.str + " and ");
System.out.println(ex.ch);
}
}

class Test1 {
String str = new String("ly");
final char[] ch = {'j', 'a', 'v', 'a'};

public void change(String str, char ch[]) {
str = "java";
ch[0] = 'h';
}
}

输出结果为:

ly and 
hava



C 0条回复 评论

帖子还没人回复快来抢沙发