|
| 1 | +package com.wang.code; |
| 2 | + |
| 3 | +public class StringDemo { |
| 4 | + |
| 5 | + public static void main(String[] args) { |
| 6 | + |
| 7 | + /* |
| 8 | + * ---------------------------------第一部分:两个字符串是否相等----------------------------------------- |
| 9 | + */ |
| 10 | + |
| 11 | + // 1 对比两个对象是否相等 |
| 12 | + String st1 = "abc"; |
| 13 | + String st2 = "abc"; |
| 14 | + System.out.println(st1 == st2); // true 很简单,程序运行时首先在常量池中创建"abc"对象,分别赋给st1和st2对象,也就是两个对象的指针相同 |
| 15 | + System.out.println(st1.equals(st2)); // true String重写了equals方法,对比char[]数组长度和值(jdk9以后为byte数组) 默认的Object的equals方法是 == |
| 16 | + |
| 17 | + String st3 = new String("abc"); |
| 18 | + String st4 = "abc"; |
| 19 | + System.out.println(st3 == st4); // false 不同的两个对象,内存地址当然不同 |
| 20 | + System.out.println(st3.equals(st4)); // true String重写了equals方法,对比的是char数组,相等 |
| 21 | + |
| 22 | + String st5 = "a" + "b" + "c"; |
| 23 | + String st6 = "abc"; |
| 24 | + System.out.println(st5 == st6); // true java的常量优化,编译期做了编译优化 |
| 25 | + System.out.println(st5.equals(st6)); |
| 26 | + |
| 27 | + String st7 = "ab"; |
| 28 | + String st8 = "abc"; |
| 29 | + String st9 = st1 + "c"; |
| 30 | + System.out.println(st8 == st9); // false |
| 31 | + System.out.println(st8.equals(st9)); // true |
| 32 | + |
| 33 | + // 以上的这些看一下编译的代码就清晰多了 |
| 34 | + // 下面是字符串原本的写法和编译之后的结果 |
| 35 | + // ---------源代码-------- |
| 36 | + //String s1 = "ABCD"; |
| 37 | + //String s2 = "A"+"B"+"C"+"D"; |
| 38 | + //String s3 = "AB"+"CD"; |
| 39 | + //String s4 = new String("ABCD"); |
| 40 | + //String t = "AB"; |
| 41 | + //String s5 = t+"CD"; |
| 42 | + // ---------编译代码-------- |
| 43 | + //String s1 = "ABCD"; |
| 44 | + //String s2 = "ABCD"; |
| 45 | + //String s3 = "ABCD"; |
| 46 | + //String s4 = new String("ABCD"); |
| 47 | + //String t = "AB"; |
| 48 | + //String s5 = (new StringBuilder(String.valueOf(t))).append("CD").toString(); |
| 49 | + |
| 50 | + |
| 51 | + /* |
| 52 | + * -----------------------------第二部分:下面这句话在内存中创建了几个对象---------------------------------- |
| 53 | + */ |
| 54 | + // 创建了两个对象,首先在常量池中创建"abc"对象;在堆中new一个String对象,堆对象是常量池对象的拷贝副本 |
| 55 | + String string = new String("abc"); |
| 56 | + |
| 57 | + |
| 58 | + /* |
| 59 | + * -----------------------------------------第三部分:源码--------------------------------------------- |
| 60 | + */ |
| 61 | + |
| 62 | + /* |
| 63 | + * String: |
| 64 | + * 它是典型的 Immutable 类,被声明成为 final class,所有属性也都是 final 的。 |
| 65 | + * 也由于它的不可变性,类似拼接、裁剪字符串等动作,都会产生新的 String 对象。 |
| 66 | + * 由于字符串操作的普遍性,所以相关操作的效率往往对应用性能有明显影响。 |
| 67 | + */ |
| 68 | + |
| 69 | + /* |
| 70 | + * StringBuilder和StringBuffer |
| 71 | + * 两个类底层都是基于char数组(jdk9为byte数组)实现的,二者都继承了 AbstractStringBuilder |
| 72 | + * 区别仅在于最终的方法是否加了 synchronized。 |
| 73 | + * 内部数组的大小为初始字符串长度+16,如果一开始能确定字符串的大小应该指定合适的大小,以避免多次扩容 |
| 74 | + * |
| 75 | + * 初始化:初始化的内部数组的大小为16或者初始字符串长度+16 |
| 76 | + * append方法:如果是null,则append "null"四个字符,否则将数组的值copy到自己的数组中 |
| 77 | + * 扩容:每次扩容的大小为 (value.length << 1) + 2 |
| 78 | + */ |
| 79 | + |
| 80 | + new StringBuilder("wang"); |
| 81 | + |
| 82 | + /* |
| 83 | + * 字符串缓存: |
| 84 | + * 在我们创建字符串对象并调用 intern() 方法的时候,如果已经有缓存的字符串,就会返回缓存里的实例,否则将其缓存起来。 |
| 85 | + */ |
| 86 | + |
| 87 | + } |
| 88 | +} |
0 commit comments