认识String类(一)

目录

1.初识字符串

 2.字符串常量池

3.反射修改常量字符串


1.初识字符串

         Java中,字符串类型就是我们用双引号引起来的连续字符,如:"abcdef",而'a'这种的只是字符,String只是字符串的类型。

那我们接下来看看一些字符串是否相等的例子:

 public static void func(String s,char[] array){
        s = "hang";
        array[0] = 'p';
    }

    public static void main(String[] args) {
         String str = "abcdef";
         char[] chars = {'b','i','t'};
         func(str,chars);
        System.out.println(str);
        System.out.println(Arrays.toString(chars));
    }

认识String类(一)_第1张图片

 下面我们看看此题的内存布局:

认识String类(一)_第2张图片

 2.字符串常量池

运行时常量池:当程序把编译好的字节码文件加载到JVM中,会生成一个运行时常量池(存储在方法区)实际上是class文件常量池。

字符串常量池:主要存放字符串常量,本质上是一个哈希表,StringTable.在JDK1.8开始,放在了堆里面。

例2:

        String str1 = "hello";//双引号引起来的存放到字符串常量池里面
        String str2 = new String("hello");
        System.out.println(str1 == str2);
//其结果是false

下面是其内存布局:

认识String类(一)_第3张图片

 例2:

String str1 = "hello";
String str2 = "hello";
System.out.println(str1 == str2);

这其中str1先入常量池,随后str2直接引用常量池中的hello,因此两者相等。并且str2并不会入池。

例3:

        String str1 = "11";
        String str2 = new String("1")+new String("1");
        System.out.println(str1 == str2);

认识String类(一)_第4张图片

 例4:

        String str2 = new String("1")+new String("1");
        str2.intern();//手动入池,字符串常量池没有的时候,就会入池,有则不会入池
        String str1 = "11";
        System.out.println(str1 == str2);

          此时两个1互相拼接之后,内存布局和上述相同,可是调用intern( )方法之后,我们将str2手动入池,之后再有str1=11调用常量池中的11,因此结果为true.

        但如果我们将str1和str2位置交换,则结果会变为false。这是因为str1先入池,之后intern( )时,常量池已经有11,因此str2不会入池。

        String str1 = "11";
        String str2 = new String("1")+new String("1");
        str2.intern();//手动入池,字符串常量池没有的时候,就会入池,有则不会入池
        System.out.println(str1 == str2);

认识String类(一)_第5张图片

 如果我们想比较字符串的内容时,则使用equals方法,但在使用之前我们应该先判断str1是否为空

public class TestDemo2 {
    public static void main7(String[] args) {
        String str1 = null;//代表str1这个引用不指向任何对象
        String str3 = "";//代表str3这个引用指向的字符串是空的
        String str2 = "11";//String底层是个value数组,此时11不能被改变,如果想改变,只能用反射
        //调用方法之前一定是个引用或者类名,因此一定要防止其为空
        System.out.println(str1.equals(str2));
    }

3.反射修改常量字符串

public static void main(String[] args) throws NoSuchFieldException {
       String str = "aello";
       Class c1 = String.class;
        // 获取 String 类中的 value 字段. 这个 value 和 String 源码中的 value 是匹配的.
        Field valueField = c1.getDeclaredField("value");
       // 将这个字段的访问属性设为 true
        valueField.setAccessible(true);
       // 把 str 中的 value 属性获取到.
        char[] value = (char[]) valueField.get(str);
       // 修改 value 的值
        value[0] = 'h';
        System.out.println(str);
    }
//此时通过反射将字符串改为hello

你可能感兴趣的:(javaSE,p2p,android,网络协议)