一污茵、簡(jiǎn)介Object類(lèi)
? ? 1、Object類(lèi)是所有類(lèi)的父類(lèi),即每個(gè)類(lèi)都直接或簡(jiǎn)介繼承自該類(lèi)葬项。所以一個(gè)Object類(lèi)型的變量可以引用任何對(duì)象,不論是類(lèi)實(shí)例還是數(shù)組。
? ? 在不明確給出父類(lèi)的情況下,Java會(huì)自動(dòng)把Object作為要定義類(lèi)的父類(lèi)民珍。
? ? Object類(lèi)有一個(gè)默認(rèn)構(gòu)造方法public Object(),在構(gòu)造子類(lèi)實(shí)例時(shí),都會(huì)先調(diào)用這個(gè)默認(rèn)構(gòu)造方法襟士。
?二嚷量、方法預(yù)覽
? ? 1陋桂、Object()
? ? ?默認(rèn)構(gòu)造方法
? ? 2蝶溶、clone()
? ? ?創(chuàng)建并返回此對(duì)象的一個(gè)副本(復(fù)制對(duì)象)
? ? 3嗜历、equals(Object obj)
? ? ?指示某個(gè)其他對(duì)象是否與此對(duì)象"相等"宣渗。
? ? 4梨州、finalize()
? ? ?當(dāng)垃圾回收器確定不存在對(duì)該對(duì)象的更多引用時(shí),由對(duì)象的垃圾回收器調(diào)用此方法,該方法用于釋放資源痕囱。
? ? 5、getClass()
? ? ?返回一個(gè)對(duì)象的運(yùn)行時(shí)類(lèi),獲得類(lèi)型的信息鞍恢。
? ? 6、hashcode()
? ? ?該方法將對(duì)象的內(nèi)存地址進(jìn)行哈希運(yùn)算,返回一個(gè)int類(lèi)型的哈希值(返回該對(duì)象的哈希碼值)每窖。
? ? ?功能:是相等對(duì)象擁有相同的哈希碼,盡量讓不等的對(duì)象具有不同的哈希碼。
? ? 7窒典、notify()
? ? ?喚醒在此對(duì)象監(jiān)視器上等待的單個(gè)線(xiàn)程蟆炊。
? ? 8瀑志、notifyAll()
? ? ?喚醒在次對(duì)象監(jiān)視器上等待的所有線(xiàn)程涩搓。
? ? 9、toString()
? ? ?返回該對(duì)象的字符串表示后室。以便用戶(hù)能夠獲得一些有關(guān)對(duì)象狀態(tài)的基本信息混狠。簡(jiǎn)單說(shuō)就是利用字符串來(lái)表示對(duì)象岸霹。
? ? 10、wait()
? ? ?導(dǎo)致當(dāng)前的線(xiàn)程等待,直到其他線(xiàn)程調(diào)用此對(duì)象的notify()方法或notifyAll()方法将饺。
? ? 11、wait(long timeout)
? ? ?導(dǎo)致當(dāng)前的線(xiàn)程等待,直到其他線(xiàn)程調(diào)用此對(duì)象的notify()方法或notifyAll()方法,或者超過(guò)指定的時(shí)間量予弧。
? ? 12刮吧、wait(long timeout, int nanos)
? ? ?導(dǎo)致當(dāng)前的線(xiàn)程等待,直到其他線(xiàn)程調(diào)用此對(duì)象的notify()方法或notifyAll方法,或者其他某個(gè)線(xiàn)程中斷當(dāng)前線(xiàn)程,或者已超過(guò)某個(gè)實(shí)際時(shí)間量掖蛤。
?三杀捻、
? ?1蚓庭、為什么要重寫(xiě)equals()方法?
? ? 因?yàn)镺bject類(lèi)中定義的equals()方法是用來(lái)比較兩個(gè)引用所指向的對(duì)象的內(nèi)存地址是否一致致讥。
? ? 源碼:
? ? public boolean equals(Object obj) {
? ? ? ? return (this == obj);
? ? }
? ? ?("=="兩邊是基本類(lèi)型比較的是內(nèi)容,"=="兩邊是引用類(lèi)型(class)比較的是否對(duì)同一對(duì)象的引用,即比較兩個(gè)引用所指向的對(duì)象的內(nèi)存地址是否一致垢袱。)
? ? 而我們經(jīng)常會(huì)希望兩個(gè)不同對(duì)象的某些屬性值相同時(shí),就認(rèn)為它們相同。所以我們要重新equals()方法港柜。
? ?2请契、為什么要重寫(xiě)hashCode()方法?
? ?需要注意的是:
? ? a、在java應(yīng)用程序運(yùn)行時(shí),無(wú)論何時(shí)多次調(diào)用同一個(gè)對(duì)象時(shí)的hashCode()方法,這個(gè)對(duì)象的hashCode()方法的返回值必須是相同的一個(gè)int值
? ? b爽锥、如果兩個(gè)對(duì)象equals()返回值為true,則它們的hashCode()也必須返回相同的int值
? ? c涌韩、如果兩個(gè)對(duì)象equals()返回值為false,則它們的hashCode()返回值也必須不同
? ? 由于hashCode方法定義在Object類(lèi)中,因此每個(gè)對(duì)象都有一個(gè)默認(rèn)的散列碼,其值為對(duì)象的存儲(chǔ)地址救恨。如果重新定義equals方法,就必須重新定義hashCode方法,以便用戶(hù)可以將對(duì)象插入到散列表中贸辈。(要保證上面所述b,c原則)
二肠槽、Java - String 類(lèi)常用方法
JackWu ?JavaGolang??3月18日
字符串操作是計(jì)算機(jī)程序設(shè)計(jì)中最常見(jiàn)的行為擎淤,本文繼續(xù)介紹 String 類(lèi)常用方法。
重載 "+" 與 StringBuilder
我們都知道 String 對(duì)象是不可變的秸仙,可以給一個(gè) String 對(duì)象加任意多個(gè)別名,因?yàn)樗哂兄蛔x特性寂纪,所以指向它的任何一個(gè)引用都不會(huì)改變它的值席吴,因此任意多個(gè)引用也不會(huì)有什么相互影響捞蛋。
但是這樣的不可變性會(huì)帶來(lái)一定的效率問(wèn)題孝冒,比如 String 對(duì)象重載的 "+" 操作符,操作符重載的含義:一個(gè)操作符應(yīng)用于特定的類(lèi)時(shí)庄涡,被設(shè)計(jì)者賦予了特殊含義(在 Java 中 String 類(lèi)僅有 “+” 和 “+=” 兩個(gè)重載操作符)。
測(cè)試代碼:
publicclassTestString{
publicstaticvoidmain(String[]?args){
String?str?="a"+"b"+10;
System.out.println(str);
}
}
反編譯結(jié)果:
Code:
0:?ldc#2//?String?a
2:?astore_1
3:?new#3//?class?java/lang/StringBuilder
6:?dup
7:?invokespecial#4//?Method?java/lang/StringBuilder."<init>":()V
10:?aload_1
11:?invokevirtual#5//?Method?java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
14:?ldc#6//?String?b10
16:?invokevirtual#5//?Method?java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
19:?invokevirtual#7//?Method?java/lang/StringBuilder.toString:()Ljava/lang/String;
22:?astore_1
23:?getstatic#8//?Field?java/lang/System.out:Ljava/io/PrintStream;
26:?aload_1
27:?invokevirtual#9//?Method?java/io/PrintStream.println:(Ljava/lang/String;)V
30:?return
我們可以驚奇的發(fā)現(xiàn):代碼中使用的是 “+” 重載符搬设,沒(méi)有使用到 StringBuilder 類(lèi),但是編譯器為了優(yōu)化它自作主張的使用了 StringBuilder 類(lèi)拿穴,因?yàn)?StringBuilder 類(lèi)更高效泣洞,大家會(huì)不會(huì)覺(jué)得反正編譯器可以幫我們用 StringBuilder 優(yōu)化默色,那是不是意味著我們可以隨意使用 “+” 重載操作符呢球凰?再來(lái)看下面這個(gè)例子:
測(cè)試代碼:
publicstaticvoidmain(String[]?args){
String?result?="";
for(inti?=0;?i?<100;?i?++)?{
result?+=?i;
}
System.out.println(result);
}
反編譯:
Code:
0:?ldc#2//?String
2:?astore_1
3:?iconst_0
4:?istore_2
5:?iload_2
6:?bipush100
8:?if_icmpge36
11:?new#3//?class?java/lang/StringBuilder
14:?dup
15:?invokespecial#4//?Method?java/lang/StringBuilder."<init>":()V
18:?aload_1
19:?invokevirtual#5//?Method?java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
22:?iload_2
23:?invokevirtual#6//?Method?java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
26:?invokevirtual#7//?Method?java/lang/StringBuilder.toString:()Ljava/lang/String;
29:?astore_1
30:?iinc2,1
33:goto5
36:?getstatic#8//?Field?java/lang/System.out:Ljava/io/PrintStream;
39:?aload_1
40:?invokevirtual#9//?Method?java/io/PrintStream.println:(Ljava/lang/String;)V
主要是關(guān)注編號(hào)為第 5 到第 33 : 這里明顯看出 “+=” 操作符編譯器還是使用? StringBuilder 類(lèi)進(jìn)行優(yōu)化腿宰,但是需要強(qiáng)烈注意的是:StringBuilder 的初始化是在循環(huán)體內(nèi)創(chuàng)建的呕诉,即每循環(huán)一次,就會(huì)創(chuàng)建新的 StringBuilder 對(duì)象酗失,這樣會(huì)造成大量的對(duì)象垃圾導(dǎo)致 GC 操作頻繁。
**優(yōu)化**:要進(jìn)行大量字符串拼接操作规肴,最好的方式是定義一個(gè) StringBuilder 或 StringBuffer 對(duì)象進(jìn)行字符串連接捶闸,少量的字符串拼接可以使用重載操作符 “+” 或 “+=”。
優(yōu)化代碼:
StringBuilder?sb?=newStringBuilder();
for(inti?=0;?i?<100;?i?++)?{
sb.append(i);
}
System.out.println(sb);
極容易忽略的:無(wú)意識(shí)遞歸
來(lái)看一個(gè)簡(jiǎn)單的代碼:
publicclassTestStringStackOverflow{
//?定義一個(gè)?Person?類(lèi)
staticclassPerson{
privateString?name;
publicPerson(String?name){
this.name?=?name;
}
/**
*?重寫(xiě)?toString()?方法删壮,注意最后的?this?關(guān)鍵字
*/
@Override
publicStringtoString()
{
return"Person{"+"name='"+?name?+'\''+'}'+this;
}
}
publicstaticvoidmain(String[]?args){
Person?person?=newPerson("jackwu");
System.out.println(person);
}
}
不知道各位有沒(méi)有發(fā)現(xiàn)存在什么問(wèn)題贪绘?這里一不小心寫(xiě)了無(wú)限循環(huán)的遞歸調(diào)用央碟,會(huì)導(dǎo)致`java.lang.StackOverflowError`異常税灌,所以千萬(wàn)不要在 toString() 方法輸出 this。
Exceptioninthread"main"java.lang.StackOverflowError
at?java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:449)
at?java.lang.StringBuilder.append(StringBuilder.java:136)
at?com.java.blog.base.TestStringStackOverflow$Person.toString(TestStringStackOverflow.java:19)
解決方案: 使用super.toString() 方法打印內(nèi)存地址.這里的 super 父類(lèi)是Object類(lèi)菱涤。
String 操作方法
String 操作方法當(dāng)需要改變字符串的內(nèi)容時(shí),String類(lèi)的方法都會(huì)返回一個(gè)新的String對(duì)象洛勉。如果內(nèi)容沒(méi)有發(fā)生改變粘秆,String 的方法只是返回指向原對(duì)象的引用而已收毫,這節(jié)省了存儲(chǔ)空間以及避免了額外的花銷(xiāo)攻走。
方法參數(shù),重載版本應(yīng)用
構(gòu)造器String()?
String(String original)?
String(char value[])?
String(char value[], int offset, int count)?
String(byte bytes[])
String(StringBuffer buffer)?
String(StringBuilder builder)
創(chuàng)建String對(duì)象
length()int length()String中字符的個(gè)數(shù)
charAt()charAt(int index)取得String中該索引位置上的char
getChars(),getBytes()getChars(char dst[], int dstBegin)?
getChars(int srcBegin, int srcEnd, char dst[], int dstBegin)?
getBytes(int srcBegin, int srcEnd, byte dst[], int dstBegin)?
getBytes(String charsetName)?
getBytes(Charset charset)?
getBytes()
復(fù)制char或byte到一個(gè)目標(biāo)數(shù)組中
toCharArray()char[] toCharArray()生成一個(gè)char[],包含String的所有字符
equals(),equalsIgnoreCase()boolean equals(Object anObject)?
qualsIgnoreCase(String anotherString)
比較兩個(gè)String的內(nèi)容是否相同
compareTocompareTo(String anotherString)按詞典順序比較String的內(nèi)容,比較結(jié)果為負(fù)數(shù),零或正數(shù).注意,大小寫(xiě)并不等價(jià)
containsboolean contains(CharSequence s)當(dāng)且僅當(dāng)此字符串包含指定的時(shí)此再,才返回true
contentEquals()boolean contentEquals(StringBuffer sb)?
boolean contentEquals(CharSequence cs)
如果該String與參數(shù)的內(nèi)容完全一致,則返回true
equalsIgnoreCaseboolean equalsIgnoreCase(String anotherString)與之進(jìn)行比較的String ?忽略大小寫(xiě),如果兩個(gè)String的內(nèi)容相同,則返回true
regionMatches()regionMatches(int toffset, String other, int ooffset,int len)返回boolean結(jié)果,以表明所比較區(qū)域是否相等
startsWith()boolean startsWith(String prefix, int toffset)?
boolean startsWith(String prefix)
返回boolean結(jié)果,以表明String是否以此參數(shù)起始
endsWith()boolean endsWith(String suffix)返回boolean結(jié)果,以表明此參數(shù)在String中的起始索引.lastIndexOf()是從后向前搜索
indexOf(),lastIndexOf()int indexOf(int ch)
indexOf(int ch, int fromIndex)?
int lastIndexOf(int ch)
lastIndexOf(int ch, int fromIndex)
如果該String并不包含此參數(shù),就返回-1;否則返回此參數(shù)在String中起始的索引.lastIndexOf()是從后向前搜索
substring(subSequence())String substring(int beginIndex)
String substring(int beginIndex, int endIndex)
CharSequence subSequence(int beginIndex, int endIndex)
返回一個(gè)新的String,以包含參數(shù)指定的子字符串
concat()String concat(String str)返回一個(gè)新的String對(duì)象,內(nèi)容為起始Stirng連接上參數(shù)String
replace()String replace(char oldChar, char newChar)返回替換字符后的新String對(duì)象.如果沒(méi)有替換發(fā)生,則返回原始的String對(duì)象
toLowerCase,toUpperCase()String toLowerCase(Locale locale)?
String toLowerCase()
String toUpperCase(Locale locale)
String toUpperCase()
將字符的大小寫(xiě)改變后,返回一個(gè)新String對(duì)象.如果沒(méi)有發(fā)生改變,則返回原始的String對(duì)象
trim()String trim()將String兩端的空白字符刪除后,返回一個(gè)新的String對(duì)象.如果沒(méi)有改變發(fā)生,則返回原始的String對(duì)象
valueOf()重載版本:Object;char[];char[],偏移量,字符個(gè)數(shù); boolean; char; int; long; float; double返回一個(gè)表示參數(shù)內(nèi)容的String
intern()native String intern()為每個(gè)唯一的字符序列生成一個(gè)且僅生成一個(gè)String引用
格式化輸出
System.out.format()
用于PrintStream或PrintWriter對(duì)象,其中包括System.out對(duì)象昔搂。
System.out.format("%-15s?%5s?%10s\n","item","qty","price");
System.out.format("%-15s?%5s?%10s\n","----","---","-----");
System.out.format("%-15.15s?%5d?%10.2f\n","lalala",4,4.25);
輸出
item??????????????qty??????price
----??????????????---??????-----
lalala44.25
Formatter類(lèi)
Formatter 類(lèi)可以將格式化字符串與數(shù)據(jù)翻譯成需要的結(jié)果,F(xiàn)ormatter類(lèi)格式化抽象語(yǔ)法: %[argument_index][flags][width][.precision]conversion
?用"-"標(biāo)志來(lái)改變對(duì)齊方向(默認(rèn)右對(duì)齊),添加了"-"表示左對(duì)齊 输拇;
width: 控制一個(gè)域的最小尺寸摘符;
precision: 用來(lái)指明最大尺寸,用于String時(shí)淳附,它表示打印String時(shí)輸出字符的最大數(shù)量.用于浮點(diǎn)數(shù)時(shí)议慰,表示小數(shù)顯示的位數(shù)(默認(rèn)6位)蠢古,小數(shù)過(guò)多則舍入,過(guò)少則在尾部補(bǔ)零,用于整數(shù)時(shí),會(huì)出發(fā)異常奴曙。
Formatter 轉(zhuǎn)換
類(lèi)型轉(zhuǎn)換字符說(shuō)明
d整數(shù)型(十進(jìn)制)
cUnicode字符
bBoolean值
sString
f浮點(diǎn)數(shù)(十進(jìn)制)
e浮點(diǎn)數(shù)(科學(xué)計(jì)數(shù)法)
x整數(shù)(十六進(jìn)制)
h散列碼(十六進(jìn)制)
%字符'%'
String.format()
是一個(gè) static 方法,接受與 Formatter.format() 方法一樣的參數(shù)草讶,但返回一個(gè) String 對(duì)象洽糟。
String.format() 內(nèi)部,它創(chuàng)建一個(gè)Formatter對(duì)象堕战,然后將你傳入的參數(shù)轉(zhuǎn)給 Formatter 坤溃。