其用javap -c 对应的路径+class文件名反编译对应的class文件得到下面的java字节码(bytecode)
1、String-概念
1.1、创建String对象的不同方式有哪些?
1、通过new关键字来创建
1-1、使用这种方式时,JVM创建字符串对象但不存储于字符串常量池。我们可以调用intern()方法将该字符串对象存储在字符串常量池,如果字符串池已经有了同样值的字符串,则返回引用。
1-2、String str = new String("abc");
2、使用双引号直接创建
2-1、使用这种方式时,JVM去字符串池找有没有值相等字符串,如果有,则返回找到的字符串引用。否则创建一个新的字符串对象并存储在字符串池。
2-2、String str = "abc"
1.2、String#.intern()方法
当intern()方法被调用,如果字符串池中含有一个字符串和当前调用方法的字符串eqauls相等,那么就会返回池中的字符串。如果池中没有的话,则首先将当前字符串加入到池中,然后返回引用。
1.3、字符串常量池存放在哪个内存区域?
1、理论知识-概括
1-1、在JDK1.6下,StringPool在永久代,通过new关键字创建出来的有两个对象,一个在常量池,一个在堆中。
1-2、JDK1.7 及之后版本的 JVM 已经将运行时常量池从方法区中移了出来,在 Java 堆(Heap)中开辟了一块区域存放运行时常量池。
1-2-1、在JDK1.7下,由于String大量的使用导致永久代经常发生OutOfMemoryError,所以将StringPool搬到heap中
1-3、JDK1.8开始,取消了Java方法区,取而代之的是位于直接内存的元空间(metaSpace)。
2、代码示例
/**
在jdk1.6中返回false,false,jdk1.7是false,true
*/
public static void main(String[] args) {
String s1 = new String("1");
s1.intern();
String s2 = "1";
System.out.println(s == s2);
String s3 = new String("1") + new String("1");
s3.intern();
String s4 = "11";
System.out.println(s3 == s4);
}
2、String-操作
2.1、判断一个String是否是回文(顺读和倒读都一样的词)
1、问题分析:
1-1、判断是否是回文,只需要比较正反是否相等即可。String类并没有提供反转方法供我们使用,但StringBuffer和StringBuilder有reverse方法。
1-2、只需要首尾一一对比
2、代码示例
/**
使用StringBuffer和StringBuilder有reverse方法。
*/
private static boolean isPalindrome(String str) {
if (str == null){
return false;
}
StringBuilder strBuilder = new StringBuilder(str);
strBuilder.reverse();
return strBuilder.toString().equals(str);
}
/**
只需要首尾一一对比,采用二分法
*/
private static boolean isPalindromeString(String str) {
if (str == null){
return false;
}
int length = str.length();
System.out.println(length / 2);
for (int i = 0; i < length / 2; i++) {
if (str.charAt(i) != str.charAt(length - i - 1))
return false;
}
return true;
}
2.2、如何比较两个字符串?
1、String内部实现了Comparable接口,有两个比较方法:compareTo(String anotherString) 和compareToIgnoreCase(String str)。
1-1、.compareTo(String anotherString)
1-1-1、与传入的anotherString字符串进行比较,如果小于传入的字符串返回负数,如果大于则返回正数。当两个字符串值相等时,返回0.此时eqauls方法会返回true。
1-1-2、源码
public int compareTo(String anotherString) {
int len1 = value.length;
int len2 = anotherString.value.length;
int lim = Math.min(len1, len2);
char v1[] = value;
char v2[] = anotherString.value;
int k = 0;
while (k < lim) {
char c1 = v1[k];
char c2 = v2[k];
if (c1 != c2) {
return c1 - c2;
}
k++;
}
return len1 - len2;
}
1-2、.equalsIgnoreCase(String str)
1-2-1、内部利用了Character.toUpperCase等方法进行了大小写转换后进行比较。
1-2-2、源码
将{@code String}对象排序为{@code compareTognoreCase}。这个比较器是可串行化的。
public static final Comparator<String> CASE_INSENSITIVE_ORDER
= new CaseInsensitiveComparator();
private static class CaseInsensitiveComparator implements Comparator<String>, java.io.Serializable {
//......
}
public int compareToIgnoreCase(String str) {
return CASE_INSENSITIVE_ORDER.compare(this, str);
}
2.3、String与char互转
1、问题分析
1-1、String是一系列字符,所有我们没法转换成一个单一的char,但可以调用toCharArray() 方法将字符串转成字符数组。
2、代码示例
String str = "Java interview";
//string to char array
char[] chars = str.toCharArray();
2.4、String与字节数组[byte array]互转
1、问题分析
1-1、使用String的getBytes()方法将String转成byte数组,使用String的构造方法 new String(byte[] arr) 将byte数据转为String。
2、代码示例
String str = "PANKAJ";
byte[] byteArr = str.getBytes();
// print the byte[] elements
System.out.println("String to byte array: " + Arrays.toString(byteArr));
byte[] byteArray = { 'P', 'A', 'N', 'K', 'A', 'J' };
byte[] byteArray1 = { 80, 65, 78, 75, 65, 74 };
String str = new String(byteArray);
String str1 = new String(byteArray1);
System.out.println(str);
System.out.println(str1);