forked from CPU-Code/java
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathStringIntern.java
More file actions
149 lines (109 loc) · 3.96 KB
/
Copy pathStringIntern.java
File metadata and controls
149 lines (109 loc) · 3.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
/**
* User: cpucode
* Date: 2021/1/9
* Time: 15:38
* Github: https://github.com/CPU-Code
* CSDN: https://blog.csdn.net/qq_44226094
*/
package com.cpucode.java.string.table;
import org.omg.Messaging.SYNC_WITH_TRANSPORT;
import org.omg.PortableInterceptor.SYSTEM_EXCEPTION;
/**
* 如何保证变量s指向的是字符串常量池中的数据呢?
* 有两种方式:
* 方式一: String s = "shkstart";//字面量定义的方式
* 方式二: 调用intern()
* String s = new String("shkstart").intern();
* String s = new StringBuilder("shkstart").toString().intern();
*/
public class StringIntern {
public static void main(String[] args) {
test1();
test2();
test3();
test4();
test5();
test6();
}
private static void test1(){
System.out.println("test1 开始");
//在堆创建一个对象
String s = "1";
//调用此方法之前,字符串常量池中已经存在了"1"
//毫无用处
s.intern();
String s2 = "1";
//jdk6:false jdk7/8:false
System.out.println(s == s2);
//s3变量记录的地址为:new String("11")
String s3 = "1" + "1";
//执行完上一行代码以后,字符串常量池中,不存在"11"
//在字符串常量池中生成"11"
// jdk6: 创建了一个新的对象"11",也就有新的地址
// jdk7/8: 此时常量中并没有创建"11",而是创建一个指向堆空间中new String("11")的地址
s3.intern();
//s4变量记录的地址:使用的是上一行代码代码执行时,在常量池中生成的"11"的地址
//引用的s3创建的地址
String s4 = "11";
//jdk6:false jdk7/8:true
System.out.println(s3 == s4);
System.out.println("test1 结束");
System.out.println();
}
private static void test2(){
System.out.println("test2 开始");
String s1 = "1" + "1";
//执行完上一行代码以后,字符串常量池中,不存在"11"
//在字符串常量池中生成对象"11"
String s2 = "11";
//把常量池引用给s3
String s3 = s2.intern();
System.out.println(s1 == s2);
System.out.println(s2 == s3);
System.out.println("test2 结束");
System.out.println();
}
private static void test3(){
System.out.println("test3 开始");
String s2 = "cp" + "u";
//在上一行代码执行完以后,字符串常量池中并没有"ab"
//jdk6中:在串池中创建一个字符串"ab"
//jdk8中:串池中没有创建字符串"ab",而是创建一个引用,指向new String("ab"),将此引用返回
String s3 = s2.intern();
System.out.println(s2 == "cpu");
System.out.println(s3 == "cpu");
System.out.println("test3 结束");
System.out.println();
}
private static void test4(){
System.out.println("test4 开始");
String s1 = "cpu";
String s2 = "cp" + "u";
String s3 = s2.intern();
System.out.println(s2 == "cpu");
System.out.println(s3 == "cpu");
System.out.println("test4 结束");
System.out.println();
}
private static void test5(){
System.out.println("test5 开始");
//执行完以后,会在字符串常量池中会生成"cpu"
String s1 = "cpu";
//毫无用处
s1.intern();
String s2 = "cpu";
System.out.println(s1 == s2);
System.out.println("test5 结束");
System.out.println();
}
private static void test6(){
System.out.println("test6 开始");
//执行完以后,不会在字符串常量池中会生成"cpucode"
String s1 = "cpu" + "Code";
s1.intern();
String s2 = "cpuCode";
System.out.println(s1 == s2);
System.out.println("test6 结束");
System.out.println();
}
}