其用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);