按照口訣記憶:
● 數(shù)據(jù)類型:byte short int long float double boolean char
● 占用字節(jié)數(shù):12484812(byte對應(yīng)1,short對應(yīng)2,以此類推)
通過JDK源代碼可以看到,Stirng是class,是引用類型,底層用 char 數(shù)組實現(xiàn)的。
前者不正確,后者正確。
對于 short s1 = 1; s1 = s1 + 1;由于 1 是 int 類型,因此 s1+1 運算結(jié)果也是 int 型,需要強制轉(zhuǎn)換類型才能賦值給 short 型。
而 short s1 = 1; s1 += 1;可以正確編譯,因為 s1+= 1;相當(dāng)于 s1 = (short)(s1 + 1);其中有隱含的強制類型轉(zhuǎn)換。
java 是一個完全面向?qū)ο缶幊陶Z言,但是為了編程的方便還是引入了基本數(shù)據(jù)類型,為了能夠?qū)⑦@些基本數(shù)據(jù)類型當(dāng)成對象操作,Java 為每一個基本數(shù)據(jù)類型都引入了對應(yīng)的包裝類型(wrapper class),int 的包裝類就是Integer,從 Java 5 開始引入了自動裝箱/拆箱機制,使得二者可以相互轉(zhuǎn)換。
java 為每個原始類型提供了包裝類型:
● 基本數(shù)據(jù)類型: boolean,char,byte,short,int,long,float,double
● 包裝類型:Boolean,Character,Byte,Short,Integer,Long,F(xiàn)loat,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);
}
}
如果不明白原理很容易認(rèn)為兩個輸出要么都是 true 要么都是 false。首先需要注意的是 f1、f2、f3、f4 四個變量都是 Integer 對象引用,所以下面的==運算比較的不是值而是引用。裝箱的本質(zhì)是什么呢?當(dāng)我們給一個Integer 對象賦一個 int 值的時候,會調(diào)用 Integer 類的靜態(tài)方法 valueOf,如果看看valueOf的源代碼就知道發(fā)生了什么。
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 的內(nèi)部類,其代碼如下所示:
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的結(jié)果是 true,而f3==f4 的結(jié)果是false。
方法 |
解釋說明 |
char charAt(int index) |
返回指定索引處的 char 值。 |
boolean contains(CharSequence s) |
當(dāng)且僅當(dāng)此字符串包含指定的 char 值序列時,返回 true。 |
boolean endsWith(String suffix) |
測試此字符串是否以指定的后綴結(jié)束。 |
boolean equals(Object anObject) |
將此字符串與指定的對象比較。 |
boolean equalsIgnoreCase(String anotherString) |
將此 String 與另一個 String 比較,不考慮大小寫。 |
byte[] getBytes() |
使用平臺的默認(rèn)字符集將此 String 編碼為 byte 序列,并將結(jié)果存儲到一個新的 byte 數(shù)組中。 |
int indexOf(String str) |
返回指定子字符串在此字符串中第一次出現(xiàn)處的索引。 |
int lastIndexOf(String str) |
返回指定子字符串在此字符串中最右邊出現(xiàn)處的索引。 |
int length() |
返回此字符串的長度。 |
String replaceAll(String regex, String replacement) |
使用給定的 replacement 替換此字符串所有匹配給定的正則表達(dá)式的子字符串。 |
String[] split(String regex) |
根據(jù)給定正則表達(dá)式的匹配拆分此字符串。 |
boolean startsWith(String prefix) |
測試此字符串是否以指定的前綴開始。 |
String substring(int beginIndex) |
返回一個新的字符串,它是此字符串的一個子字符串。 |
String substring(int beginIndex, int endIndex) |
返回一個新字符串,它是此字符串的一個子字符串。 |
char[] toCharArray() |
將此字符串轉(zhuǎn)換為一個新的字符數(shù)組。 |
String toLowerCase() |
使用默認(rèn)語言環(huán)境的規(guī)則將此 String 中的所有字符都轉(zhuǎn)換為小寫。 |
String toUpperCase() |
使用默認(rèn)語言環(huán)境的規(guī)則將此 String 中的所有字符都轉(zhuǎn)換為大寫。 |
String trim() |
返回字符串的副本,忽略前導(dǎo)空白和尾部空白。 |
● 可變不可變
String:字符串常量,在修改時不會改變自身;若修改,等于重新生成新的字符串對象。
StringBuffer:在修改時會改變對象自身,每次操作都是對 StringBuffer 對象本身進(jìn)行修改,不是生成新的對象;使用場景:對字符串經(jīng)常改變情況下,主要方法:append(),insert()等。
● 線程是否安全
String:對象定義后不可變,線程安全。
StringBuffer:是線程安全的(對調(diào)用方法加入同步鎖),執(zhí)行效率較慢,適用于多線程下操作字符串緩沖區(qū)大量數(shù)據(jù)。
StringBuilder:是線程不安全的,適用于單線程下操作字符串緩沖區(qū)大量數(shù)據(jù)。
● 共同點
StringBuilder與StringBuffer有公共父類 AbstractStringBuilder(抽象類)。
StringBuilder、StringBuffer 的方法都會調(diào)用 AbstractStringBuilder 中的公共方法,如 super.append(...)。只是 StringBuffer 會在方法上加 synchronized 關(guān)鍵字,進(jìn)行同步。最后,如果程序不是多線程的,那么使用StringBuilder 效率高于 StringBuffer。
● 字符串如何轉(zhuǎn)基本數(shù)據(jù)類型?
調(diào)用基本數(shù)據(jù)類型對應(yīng)的包裝類中的方法 parseXXX(String)或valueOf(String)即可返回相應(yīng)基本類型。
● 基本數(shù)據(jù)類型如何轉(zhuǎn)字符串?
一種方法是將基本數(shù)據(jù)類型與空字符串(“”)連接(+)即可獲得其所對應(yīng)的字符串;另一種方法是調(diào)用 String類中的 valueOf()方法返回相應(yīng)字符串。