按照口訣記憶:
● 數據類型:byte short int long float double boolean char
● 占用字節數:12484812(byte對應1,short對應2,以此類推)
通過JDK源代碼可以看到,Stirng是class,是引用類型,底層用 char 數組實現的。
前者不正確,后者正確。
對于 short s1 = 1; s1 = s1 + 1;由于 1 是 int 類型,因此 s1+1 運算結果也是 int 型,需要強制轉換類型才能賦值給 short 型。
而 short s1 = 1; s1 += 1;可以正確編譯,因為 s1+= 1;相當于 s1 = (short)(s1 + 1);其中有隱含的強制類型轉換。
java 是一個完全面向對象編程語言,但是為了編程的方便還是引入了基本數據類型,為了能夠將這些基本數據類型當成對象操作,Java 為每一個基本數據類型都引入了對應的包裝類型(wrapper class),int 的包裝類就是Integer,從 Java 5 開始引入了自動裝箱/拆箱機制,使得二者可以相互轉換。
java 為每個原始類型提供了包裝類型:
● 基本數據類型: boolean,char,byte,short,int,long,float,double
● 包裝類型:Boolean,Character,Byte,Short,Integer,Long,Float,Double
public class Test{
public static void main(String[] args) {
Integer f1 = 100, f2 = 100, f3 = 150, f4 = 150;
System.out.println(f1 == f2);
System.out.println(f3 == f4);
}
}
如果不明白原理很容易認為兩個輸出要么都是 true 要么都是 false。首先需要注意的是 f1、f2、f3、f4 四個變量都是 Integer 對象引用,所以下面的==運算比較的不是值而是引用。裝箱的本質是什么呢?當我們給一個Integer 對象賦一個 int 值的時候,會調用 Integer 類的靜態方法 valueOf,如果看看valueOf的源代碼就知道發生了什么。
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
IntegerCache 是 Integer 的內部類,其代碼如下所示:
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[];
static {
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
try {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(I, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(I, Integer.MAX_VALUE - (-low) -1);
} catch( NumberFormatException nfe) {
// If the property cannot be parsed into an int, ignore it.
}
}
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
// range [-128, 127] must be interned (JLS7 5.1.7)
assert IntegerCache.high >= 127;
}
private IntegerCache() {}
}
簡單的說,如果整型字面量的值在-128 到 127 之間,那么不會 new 新的 Integer 對象,而是直接引用常量池中的Integer對象,所以上面的面試題中f1==f2的結果是 true,而f3==f4 的結果是false。
方法 |
解釋說明 |
char charAt(int index) |
返回指定索引處的 char 值。 |
boolean contains(CharSequence s) |
當且僅當此字符串包含指定的 char 值序列時,返回 true。 |
boolean endsWith(String suffix) |
測試此字符串是否以指定的后綴結束。 |
boolean equals(Object anObject) |
將此字符串與指定的對象比較。 |
boolean equalsIgnoreCase(String anotherString) |
將此 String 與另一個 String 比較,不考慮大小寫。 |
byte[] getBytes() |
使用平臺的默認字符集將此 String 編碼為 byte 序列,并將結果存儲到一個新的 byte 數組中。 |
int indexOf(String str) |
返回指定子字符串在此字符串中第一次出現處的索引。 |
int lastIndexOf(String str) |
返回指定子字符串在此字符串中最右邊出現處的索引。 |
int length() |
返回此字符串的長度。 |
String replaceAll(String regex, String replacement) |
使用給定的 replacement 替換此字符串所有匹配給定的正則表達式的子字符串。 |
String[] split(String regex) |
根據給定正則表達式的匹配拆分此字符串。 |
boolean startsWith(String prefix) |
測試此字符串是否以指定的前綴開始。 |
String substring(int beginIndex) |
返回一個新的字符串,它是此字符串的一個子字符串。 |
String substring(int beginIndex, int endIndex) |
返回一個新字符串,它是此字符串的一個子字符串。 |
char[] toCharArray() |
將此字符串轉換為一個新的字符數組。 |
String toLowerCase() |
使用默認語言環境的規則將此 String 中的所有字符都轉換為小寫。 |
String toUpperCase() |
使用默認語言環境的規則將此 String 中的所有字符都轉換為大寫。 |
String trim() |
返回字符串的副本,忽略前導空白和尾部空白。 |
● 可變不可變
String:字符串常量,在修改時不會改變自身;若修改,等于重新生成新的字符串對象。
StringBuffer:在修改時會改變對象自身,每次操作都是對 StringBuffer 對象本身進行修改,不是生成新的對象;使用場景:對字符串經常改變情況下,主要方法:append(),insert()等。
● 線程是否安全
String:對象定義后不可變,線程安全。
StringBuffer:是線程安全的(對調用方法加入同步鎖),執行效率較慢,適用于多線程下操作字符串緩沖區大量數據。
StringBuilder:是線程不安全的,適用于單線程下操作字符串緩沖區大量數據。
● 共同點
StringBuilder與StringBuffer有公共父類 AbstractStringBuilder(抽象類)。
StringBuilder、StringBuffer 的方法都會調用 AbstractStringBuilder 中的公共方法,如 super.append(...)。只是 StringBuffer 會在方法上加 synchronized 關鍵字,進行同步。最后,如果程序不是多線程的,那么使用StringBuilder 效率高于 StringBuffer。
● 字符串如何轉基本數據類型?
調用基本數據類型對應的包裝類中的方法 parseXXX(String)或valueOf(String)即可返回相應基本類型。
● 基本數據類型如何轉字符串?
一種方法是將基本數據類型與空字符串(“”)連接(+)即可獲得其所對應的字符串;另一種方法是調用 String類中的 valueOf()方法返回相應字符串。