版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
JAVA重難點(diǎn)問(wèn)題剖析(■)
這次主要剖析以卜.四個(gè)問(wèn)題:
構(gòu)造函數(shù)定義問(wèn)題、類(lèi)實(shí)例化時(shí)的歧義、equals和==、protected成員的訪問(wèn)問(wèn)題
(1)構(gòu)造函數(shù)前不加void,否則變?yōu)榉椒?,只能加可訪問(wèn)性修飾。
publicclassName{
voidNameO(
System,out.printIn(''Method^);
)
publicstaticvoidmain(String[]args){
Namen=newName();
}
)
無(wú)輸出,去void則輸入Method;
(2)如果需要在不同包的類(lèi)中使用構(gòu)造函數(shù)創(chuàng)建對(duì)象必須前面加上public;
二、類(lèi)實(shí)例化時(shí)的歧義問(wèn)題
(1)單類(lèi)形導(dǎo)入(即importpl.TestC而非importpl.*)時(shí)用此類(lèi)實(shí)類(lèi)化:
(2)完全標(biāo)示名解決歧義問(wèn)題pl.TestCb=ne\vpl.TestC()
packagepl;〃定義第一個(gè)類(lèi)
publicclassTestC{
publicTestCO{System.out.printin(^pl^);}
}
packagep2;〃定義第二個(gè)類(lèi)
publicclassTestC{
TestCO{System.out.printIn(,,p2/z);}
packagep2;〃定義第三個(gè)類(lèi)
importpl.*;//(1)
publicclassTestB{
publicstaticvoidmain(String[]args){
TestCc=newTestCO;//(2)
)
輸出p2,若要輸出pl,可將(1)處改為importpl.TestC或者將(2)處改為pl.TestCb=newpl.TestCO;
三、數(shù)值、對(duì)象比較問(wèn)題
java.lang,object類(lèi)中的equal()方法:
publicbooleanequals(Objectobj){
return(this=obj);
)
java.lang.string類(lèi)中覆蓋object中的equals。方法:
publicbooleanequals(ObjectanObject){
if(this==anObject){
returntrue;
)
if(anObjectinstanceofString){
StringanotherString=(String)anObject;
intn=count;
if(n==anotherString.count){
charvl[]=value;
charv2[]=anotherString.value;
inti=offset;
intj=anotherString.offset;
while(n—!=0){
if(vl[i++]!=v2[j++])
returnfalse;
)
returntrue;
}
)
returnfalse;
)
例子:
classTest{
Strings;
Test(Strings){
this.s=s;
)
)
publicclassFyz{
publicstaticvoidmain(String[]args){
Stringsl=newString(z,hello/,);
Strings2=newStringCzhello/,);
TestTl=newTest("JAVA");
TestT2=newTest("JAVA");
System.out.printin(si.equals(s2));//true:String^Boolean等類(lèi)的equals覆蓋了object的,比
較的不再是對(duì)象而是數(shù)值
System.out.printin(Tl.equals(T2));//false:沒(méi)有覆蓋object的,所以比較的仍然是對(duì)象
System,out.printin(Sl==s2);//false:二二比較的是對(duì)象,無(wú)論是什么對(duì)象;
System.out.println(Tl==T2);//false:同上
T2=T1;〃使引用變量Tl、T2都成為同一對(duì)象的別名
System,out.printin(Tl.equals(T2));〃true:對(duì)象相同
System.out.printin(T1==T2);//true:同上
)
}
四、若在不同包中子類(lèi)使用對(duì)象引用來(lái)訪問(wèn)父類(lèi)的protected成員,必須將對(duì)象實(shí)例化為子類(lèi)對(duì)象,而不
能實(shí)例為父類(lèi)對(duì)象來(lái)訪問(wèn),即子類(lèi)只能以實(shí)現(xiàn)繼承層次中的身份訪問(wèn)其超類(lèi)的protected成員。相同包子
類(lèi)中使用對(duì)象引用的類(lèi)型都可以。
packagetestl;
publicclassA{
publicvoidpublicMethod。{System.out.printin("public方法”);}
protectedvoidprotectedMethod(){System,out.printIn("protected方法”);}
voidfriendlyMethod(){System.out.printin("friendly方法〃);}
privatevoidprivateMethodO{System,out.printIn("private方法”);}
packagetestl;
publicclassExtendsAextendsA(
publicstaticvoidmain(String[]args){
AAl=newA();
Al.publicMethod();
Al.protectedMethod();
Al.friendlyMethod();
//Al.privateMethodO;
ExtendsAExtendsAl=newExtendsA0;
ExtendsAl.publicMethod();
ExtendsAl.protectedMethod();
ExtendsAl.friendlyMethod();
//ExtendsAl.privateMethodO;
)
publicvoidprintinfoO{
publicMethod();
protectedMethod();
friendlyMethodO;
//privateMethod();
)
packagetest2;
importtestl.A;
publicclassExtendsAextendsA{
publicstaticvoidmain(String[]args){
AAl=newA();
Al.publicMethod();
//Al.protectedMethod();調(diào)用不行
//Al.friendlyMethodO;
//Al.privateMethodO;
ExtendsAExtendsAl=newExtendsA();
ExtendsAl.publicMethodO;
ExtendsAl.protectedMethod();〃可以調(diào)用
//ExtendsAl.friendlyMethodO;
//ExtendsAl.privateMethodO;
)
publicvoidprintinfo(){
publicMethodO;
protectedMethod。;〃可以直接調(diào)用
//friendlyMethodO;
//privateMethod0;
)
多態(tài)與類(lèi)型轉(zhuǎn)化原理分析:
?、多態(tài)性:超類(lèi)引用在運(yùn)行時(shí)既能代衣超類(lèi)本身的對(duì)象,也能代表其子類(lèi)的對(duì)象的能力。
類(lèi)的一個(gè)成員若想表現(xiàn)多態(tài)必須可以被覆蓋:
對(duì)于成員變量而言,不會(huì)發(fā)生覆蓋現(xiàn)象(會(huì)隱藏),在子類(lèi)出現(xiàn)相同變量的定義時(shí)只會(huì)隱藏父類(lèi)變量,因此
不會(huì)表現(xiàn)多態(tài)。同時(shí)變量調(diào)用在編譯時(shí)就會(huì)解析,不符合動(dòng)態(tài)綁定的特征;
在成員方法中,靜態(tài)方法和final方法(private方法)也不會(huì)發(fā)生覆蓋現(xiàn)象(會(huì)隱藏),因此也不會(huì)表
現(xiàn)多態(tài)性。
因此只有除靜態(tài)方法和final方法以外的方法才會(huì)表現(xiàn)多態(tài)性。
:、向上類(lèi)型轉(zhuǎn)化時(shí):
丟失添加的方法和字段,剩余的為:
基類(lèi)字段
基類(lèi)靜態(tài)方法或final方法〃前二者為不能被覆蓋的成員,因此保留,無(wú)多態(tài)性
基類(lèi)其他方法(若被子類(lèi)覆蓋則為子類(lèi)覆蓋的新方法)
packagetest3;
classoopsuper{
staticStringstr="父類(lèi)字段〃;
publicvoidpublicMethodO{System.out.printing父類(lèi)public方法”);}
protectedvoidprotectedMethodO{System.out.printIn("父類(lèi)protected方法”);}〃(1)
privatevoidprivateMethodO{System.out.printIn(〃父類(lèi)private方法〃);}
staticvoidstaticMethodO{System.out.printing父類(lèi)靜態(tài)方法”);}
}
publicclassoopsubextendsoopsuper{
Stringstr=〃子類(lèi)字段〃;
publicvoidpublicMethodO{System.out.printIn(〃子類(lèi)public方法〃);}
protectedvoidprotectedMethodO{System.out.printIn("子類(lèi)protected方法”);}//(2)
privatevoidprivateMethod(){System,out.prinlln("子類(lèi)private方法”);}
staticvoidstaticMethodO{System.out.printin(“子類(lèi)靜態(tài)方法”);}
publicstaticvoidmain(String[]args){
oopsuperupcast=newoopsub();
System.out.printin(upcast,str);〃方法調(diào)用才具有多態(tài)性,而域沒(méi)有多態(tài)性
//能被覆蓋的方法的行為才仃多態(tài)特性
upcast,publicMethodO;
upcast.protectedMethodO;〃若注釋掉(1)則有錯(cuò)誤;若注釋掉(2)則輸出:子類(lèi)protected方法
//不能被覆蓋的方法[final方法(含私有方法)、靜態(tài)方法]的行為不具有多態(tài)特性
//upcast.privateMethodO;訪問(wèn)的是父類(lèi)的私有方法,不能訪問(wèn),不具有多態(tài)現(xiàn)象
upcast.staticMethodO;
}
JAVA重難點(diǎn)問(wèn)題剖析(二)
Byfengyuzhe發(fā)表于2007-12-1412:44:00
0
這次主要剖析以下問(wèn)題:
抽象類(lèi)與接口的區(qū)別、別名、局部變量的語(yǔ)句塊作用域、this構(gòu)造和super構(gòu)造
一、抽象類(lèi)與接口的區(qū)別:
*1.抽象類(lèi)中可以定義所有成員變量(含實(shí)例變量和靜態(tài)變量[含常量])和非空方法,而接口中只能定義
常量和空方法;
*2.抽象類(lèi)在定義抽象方法時(shí)必須加abstract,而在接口中可以加但不需要加;
*3.接口允許多繼承:一個(gè)接口可以基層多個(gè)接口,實(shí)現(xiàn)接口的類(lèi)也可以繼承多個(gè)接口,但JAVA的類(lèi)僅
支持單繼承。
packagetest;
interfaceobject1{
//intvarl;
//staticintvarls;
intVARI=2;//接口中只能定義常量,等同于finalstaticintVAR1=2;
intinterfaceMethodl();
abstractintinterfaceMethod2();〃接口中的方法其實(shí)就是抽象方法,但在接口中一般不加abstra
ct
//intinferfaceMethod3(){)接口中不能含有非抽象方法
}
abstractclassobject2{
intvar2;
staticintvar2s;
finalstaticintVAR2=2;〃抽象類(lèi)中可以定義變量也可以定義常量
abstractintabstractMethodl();
//intabstractMethod2();空方法必須加abstract修飾符
//abstractintabstractMethod3(){}抽象方法不能指定方法體
voidabstractMethod4(){}〃抽象類(lèi)中可以含有非抽象方法
)
二、卜.面中的引用變量都是別名
packagetest2;
publicclasstest{
inta;
publictest(inti){
this,a=i;
)
publicstaticvoidmain(String[]args){
testtest1=newtest(10);
testtest2=testl;
System,out.printin(testl.a);
System,out.println(test2.a);
testl=null;
//System.out.println(testl.a);
System,out.printIn(test2.a);
)
三、局部變量的語(yǔ)句塊作用域:
語(yǔ)句塊{}中所聲明的變量的作用域處在聲明該變量的語(yǔ)句塊中,語(yǔ)句塊外部不能訪問(wèn)
publicclasshong{
publicstaticvoidmain(String[]args){
intvarl=1;
{
intvar2=2;
}
System,out.printIn(varl);
//System.out.println(var2);
//var2不能別解析,因?yàn)関ar2的作用域處在語(yǔ)句塊。中
)
)
四、this構(gòu)造和super構(gòu)造
二者必須位于構(gòu)造函數(shù)的第?行,this。構(gòu)造用于串鏈同個(gè)類(lèi)中的構(gòu)造函數(shù),而super()構(gòu)造用于激活超
類(lèi)的構(gòu)造函數(shù),如果構(gòu)造函數(shù)的第一句不是this。構(gòu)造或者super()構(gòu)造,則會(huì)插入一條指向超類(lèi)默認(rèn)構(gòu)
造函數(shù)的super()調(diào)用
classtest{
inti,j;
test(inti,intj){
this,i=i;
this,j=j;
)
)
publicclassSuperDemoextendstest{
intk,1;
SuperDemo(){
thisdl,12);
)
/*錯(cuò)誤,插入插入一條指向超類(lèi)默認(rèn)構(gòu)造函數(shù)的super()調(diào)用
SuperDemo(inti,intj){
this,k=i;
this.1=j;
)
*/
publicstaticvoidmain(String[]args){
SuperDemosd=newSuperDemo();
System,out.print(sd.i+"〃+sd.j+sd.k+sd.1);
)
一.Input和Output
1.stream代表的是任何有能力產(chǎn)出數(shù)據(jù)的數(shù)據(jù)源,或是任何有能力接收數(shù)據(jù)的接收源。在Java的I0中,
所有的stream(包括Input和Outstream)都包括兩種類(lèi)型:
1.1以字節(jié)為導(dǎo)向的stream
以字節(jié)為導(dǎo)向的stream,表示以字節(jié)為單位從stream中讀取或往stream中寫(xiě)入信息。以字節(jié)為導(dǎo)向
的stream包括卜.面幾種類(lèi)型:
1)inputstream:
1)ByteArraylnputStream:把內(nèi)存中的一個(gè)緩沖區(qū)作為Inputstream使用
2)StringBufferInputStream:把一個(gè)String對(duì)象作為Inputstream
3)FilelnputStream:把一個(gè)文件作為Inputstream,實(shí)現(xiàn)對(duì)文件的讀取操作
4)PipedlnputStream:實(shí)現(xiàn)了pipe的概念,主要在線程中使用
5)Sequenceinputstream:把多個(gè)Inputstream合并為一個(gè)InputStream
2)Outstream
1)ByteArrayOutputStream:把信息存入內(nèi)存中的一個(gè)緩沖區(qū)U」
2)FileOutputStream:把信息存入文件中
3)PipedOutputStream:實(shí)現(xiàn)了pipe的概念,主要在線程中使用
4)SequenceOutputStream:把多個(gè)OutStream合并為OutStream
1.2以Unicode字符為導(dǎo)向的stream
以Unicode字符為導(dǎo)向的stream,表示以Unicode字符為單位從stream中讀取或往stream中寫(xiě)入
信息。以Unicode字符為導(dǎo)向的stream包括下面幾種類(lèi)型:
1)InputStream
1)CharArrayReader:與ByteArraylnputStream對(duì)應(yīng)
2)StringReader:StringBufferlnputStream對(duì)應(yīng)
3)FileReader:與FilelnputStream對(duì)應(yīng)
4)PipedReader:與PipedlnputStream對(duì)應(yīng)
2)OutStream
1)CharArrayWrite:與ByteArrayOutputStream對(duì)應(yīng)
2)StringWrite:無(wú)與之對(duì)應(yīng)的以字節(jié)為導(dǎo)向的stream
3)FileWrite:與FileOutputStream對(duì)應(yīng)
4)PipedWrite:與PipedOutputStream對(duì)應(yīng)
以字符為導(dǎo)向的stream基本上對(duì)有與之相對(duì)應(yīng)的以字節(jié)為導(dǎo)向的stream。兩個(gè)對(duì)應(yīng)類(lèi)實(shí)現(xiàn)的功能相同,
字是在操作時(shí)的導(dǎo)向不同。如CharArrayReader:和ByteArraylnputStream的作用都是把內(nèi)存中的
一個(gè)緩沖區(qū)作為Inputstream使用,所不同的是前者每次從內(nèi)存中讀取一個(gè)字節(jié)的信息,而后者每次從
內(nèi)存中讀取一個(gè)字符。
1.3兩種不現(xiàn)導(dǎo)向的stream之間的轉(zhuǎn)換
InputstreamR6ader和OutputstreamReader:把一個(gè)以字節(jié)為導(dǎo)向的stream轉(zhuǎn)換成一個(gè)以字符為
導(dǎo)向的stream。
2.stream添加屬性
2.1"為stream添加屬性”的作用
運(yùn)用上面介紹的Java中操作I0的API,我們就可完成我們想完成的任何操作了。但通過(guò)
Filterinputstream和FilterOutStream的子類(lèi),我們可以為stream添加屬性。F面以一個(gè)例子來(lái)說(shuō)
明這種功能的作用。
如果我們要往一個(gè)文件中寫(xiě)入數(shù)據(jù),我們可以這樣操作:
FileOutStreamfs=newFileOutStream(Mtest.txt");
然后就可以通過(guò)產(chǎn)生的fs對(duì)象調(diào)用write。函數(shù)來(lái)往test.txt文件中寫(xiě)入數(shù)據(jù)了。但是,如果我們想實(shí)現(xiàn)
“先把要寫(xiě)入文件的數(shù)據(jù)先緩存到內(nèi)存中,再把緩存中的數(shù)據(jù)寫(xiě)入文件中”的功能時(shí),I二面的API就沒(méi)有一
個(gè)能滿足我們的需求了。但是通過(guò)Filterinputstream和FilterOutStream的子類(lèi),FileOutStream
添加我們所需要的功能。
2.2Filterinputstream的各種類(lèi)型
2.2.1用于封裝以字節(jié)為導(dǎo)向的Inputstream
1)DatalnputStream:從stream中讀取基本類(lèi)型(int、char等)數(shù)據(jù)。
2)BufferedlnputStream:使用緩沖區(qū)
3)LineNumberlnputStream:會(huì)記錄inputstream內(nèi)的行數(shù),然后可以調(diào)用getLineNumber()和
setLineNumber(int)
4)PushbacklnputStream:很少用到,一般用于編譯器開(kāi)發(fā)
2.2.2用于封裝以字符為導(dǎo)向的Inputstream
1)沒(méi)有與DatalnputStream對(duì)應(yīng)的類(lèi)。除非在要使用readLine。時(shí)改用BufferedReader,否則使用
DatalnputStream
2)BufferedReader:與BufferedlnputStream對(duì)應(yīng)
3)LineNumberReader:與LineNumberlnputStream對(duì)應(yīng)
4)PushBackReader:與PushbacklnputStream對(duì)應(yīng)
2.3FilterOutStream的各種類(lèi)型
2.2.3用于封裝以字節(jié)為導(dǎo)向的Outputstream
1)DatalOutStream:往stream輸出基本類(lèi)型(int、char等)數(shù)據(jù)。
2)BufferedOutStream:使用緩沖區(qū)
3)Printstream:產(chǎn)生格式化輸出
2.2.4用于封裝以字符為導(dǎo)向的Outputstream
1)BufferedWrite:與對(duì)應(yīng)
2)PrintWrite:與對(duì)應(yīng)
3.RandomAccessFile
1)可通過(guò)RandomAccessFile對(duì)象完成對(duì)文件的讀寫(xiě)操作
2)在產(chǎn)生一個(gè)對(duì)象時(shí),可指明要打開(kāi)的文件的性質(zhì):r,只讀:w,只寫(xiě);rw可讀寫(xiě)
3)可以直接跳到文件中指定的位置
4.I/O應(yīng)用的一個(gè)例子
importjava.io.*;
publicclassTestlO{
publicstaticvoidmain(String[]args)
throwsIOException{
〃1.以行為單位從一個(gè)文件讀取數(shù)據(jù)
BufferedReaderin=
newBufferedReader(
newFileReader("F:\\nepalon\\TestlO.java"));
Strings,s2=newString();
while((s=in.readLine())!=null)
s2+=s+M\nM;
in.close();
//1b.接收鍵盤(pán)的輸入
BufferedReaderstdin=
newBufferedReader(
newInputStreamReader(System.in));
System.out.println(HEnteraline:");
System.out.println(stdin.readLine());
//2.從一個(gè)String對(duì)象中讀取數(shù)據(jù)
StringReaderin2=newStringReader(s2);
intc;
while((c=in2.read())!=-1)
System.out.printin((char)c);
in2.close();
//3.從內(nèi)存取出格式化輸入
try{
DatalnputStreamin3=
newDatalnputStream(
newByteArraylnputStream(s2.getBytes()));
while(true)
System.out.printin((char)in3.readByte());
)
catch(EOFExceptione){
System.out.println(,'Endofstream");
)
//4.輸出到文件
try(
BufferedReaderin4=
newBufferedReader(
newStringReader(s2));
PrintWriterout1=
newPrintWriter(
newBufferedWriter(
newFileWriter("F:\\nepalon\\TestlO.out")));
intlineCount=1;
while((s=in4.readLine())!=null)
Java本質(zhì)論之關(guān)于Java棧與堆的思考
原文地址http:〃/edu/ShowArticle.asD?ArticlelD=1539
1.棧(stack)與堆(heap)都是Java用來(lái)在Ram中存放數(shù)據(jù)的地方。與C++不同,Java自動(dòng)
管理?xiàng):投?,程序員不能直接地設(shè)置?;蚨?。
2.棧的優(yōu)勢(shì)是,存取速度比堆要快,僅次于直接位于CPU中的寄存器。但缺點(diǎn)是,存在棧
中的數(shù)據(jù)大小與生存期必須是確定的,缺乏靈活性。另外,棧數(shù)據(jù)可以共享,詳見(jiàn)第3點(diǎn)。
堆的優(yōu)勢(shì)是可以動(dòng)態(tài)地分配內(nèi)存大小,生存期也不必事先告訴編譯器,Java的垃圾收集器
會(huì)自動(dòng)收走這些不再使用的數(shù)據(jù)。但缺點(diǎn)是,由于要在運(yùn)行時(shí)動(dòng)態(tài)分配內(nèi)存,存取速度較慢。
3.Java中的數(shù)據(jù)類(lèi)型有兩種。
一種是基本類(lèi)型(primitivetypes),共有8種,即int,short,long,byte,float,double,boolean,
char(注意,并沒(méi)有string的基本類(lèi)型)。這種類(lèi)型的定義是通過(guò)諸如inta=3;longb=255L;
的形式來(lái)定義的,稱為自動(dòng)變量。值得注意的是,自動(dòng)變量存的是字面值,不是類(lèi)的實(shí)例,
即不是類(lèi)的引用,這里并沒(méi)有類(lèi)的存在。如inta=3;這里的a是一個(gè)指向int類(lèi)型的引用,
指向3這個(gè)字面值。這些字面值的數(shù)據(jù),由于大小可知,生存期可知(這些字面值固定定義
在某個(gè)程序塊里面,程序塊退出后,字段值就消失了),出于追求速度的原因,就存在于棧
中。
另外,棧有一個(gè)很重要的特殊性,就是存在棧中的數(shù)據(jù)可以共享。假設(shè)我們同時(shí)定義:
inta=3;
intb=3;
編譯器先處理inta=3;首先它會(huì)在棧中創(chuàng)建一個(gè)變量為a的引用,然后查找有沒(méi)有字面值
為3的地址,沒(méi)找到,就開(kāi)辟一個(gè)存放3這個(gè)字面值的地址,然后將a指向3的地址。接
著處理intb=3;在創(chuàng)建完b的引用變量后,山于在棧中已經(jīng)有3這個(gè)字面值,便將b直接
指向3的地址。這樣,就出現(xiàn)了a與b同時(shí)均指向3的情況。
特別注意的是,這種字面值的引用與類(lèi)對(duì)象的引用不同。假定兩個(gè)類(lèi)對(duì)象的引用同時(shí)指向一
個(gè)對(duì)象,如果一個(gè)對(duì)象引用變量修改了這個(gè)對(duì)象的內(nèi)部狀態(tài),那么另一個(gè)對(duì)象引用變量也即
刻反映出這個(gè)變化。相反,通過(guò)字面值的引用來(lái)修改其值,不會(huì)導(dǎo)致另一個(gè)指向此字面值的
引用的值也跟著改變的情況。如上例,我們定義完a與b的值后,再令a=4;那么,b不會(huì)
等于4,還是等于3。在編譯器內(nèi)部,遇到a=4;時(shí),它就會(huì)重新搜索棧中是否有4的字面
值,如果沒(méi)有,重新開(kāi)辟地址存放4的值;如果已經(jīng)有了,則直接將a指向這個(gè)地址。因
此a值的改變不會(huì)影響到b的值。
另一種是包裝類(lèi)數(shù)據(jù),如Integer,String,Double等將相應(yīng)的基本數(shù)據(jù)類(lèi)型包裝起來(lái)的類(lèi)。
這些類(lèi)數(shù)據(jù)全部存在于堆中,Java用new()語(yǔ)句來(lái)顯示地告訴編譯器,在運(yùn)行時(shí)才根據(jù)需
要?jiǎng)討B(tài)創(chuàng)建,因此比較靈活,但缺點(diǎn)是要占用更多的時(shí)間。4.String是一個(gè)特殊的包裝類(lèi)
數(shù)據(jù)。即可以用Stringstr=newString("abc");的形式來(lái)創(chuàng)建,也可以用Stringstr="abe";
的形式來(lái)創(chuàng)建(作為對(duì)比,在JDK5.0之前,你從未見(jiàn)過(guò)Integeri=3;的表達(dá)式,因?yàn)轭?lèi)與
字面值是不能通用的,除了String。而在JDK5.0中,這種表達(dá)式是可以的!因?yàn)榫幾g器在
后臺(tái)進(jìn)行Integeri=newlnteger(3)的轉(zhuǎn)換)。前者是規(guī)范的類(lèi)的創(chuàng)建過(guò)程,即在Java中,
一切都是對(duì)象,而對(duì)象是類(lèi)的實(shí)例,全部通過(guò)new()的形式來(lái)創(chuàng)建。Java中的有些類(lèi),如
DateFormat類(lèi),可以通過(guò)該類(lèi)的getlnstance()方法來(lái)返回一個(gè)新創(chuàng)建的類(lèi),似乎違反了此
原則。其實(shí)不然。該類(lèi)運(yùn)用了單例模式來(lái)返回類(lèi)的實(shí)例,只不過(guò)這個(gè)實(shí)例是在該類(lèi)內(nèi)部通過(guò)
new()來(lái)創(chuàng)建的,而getlnstance()向外部隱藏了此細(xì)節(jié)。那為什么在Stringstr="abc";中,
并沒(méi)有通過(guò)new()來(lái)創(chuàng)建實(shí)例,是不是違反了上述原則?其實(shí)沒(méi)有。
5.關(guān)于Stringstr="abc"的內(nèi)部工作。Java內(nèi)部將此語(yǔ)句轉(zhuǎn)化為以下幾個(gè)步驟:
⑴先定義一個(gè)名為str的對(duì)String類(lèi)的對(duì)象引用變量:Stringstr;
(2)在棧中查找有沒(méi)有存放值為"abc"的地址,如果沒(méi)有,則開(kāi)辟一個(gè)存放字面值為"abc"的地
址,接著創(chuàng)建一個(gè)新的String類(lèi)的對(duì)象o,并將。的字符串值指向這個(gè)地址,而且在棧中這
個(gè)地址旁邊記下這個(gè)引用的對(duì)象。。如果已經(jīng)有了值為"abc"的地址,則查找對(duì)象。,并返回
o的地址。
⑶將str指向?qū)ο髈的地址。
值得注意的是,一般String類(lèi)中字符串值都是直接存值的。但像Stringstr="abc";這種場(chǎng)
合下,其字符串值卻是保存了一個(gè)指向存在棧中數(shù)據(jù)的引用!
為了更好地說(shuō)明這個(gè)問(wèn)題,我們可以通過(guò)以下的幾個(gè)代碼進(jìn)行驗(yàn)證。
Stringstr1="abc";
Stringstr2="abc";
System.out.println(str1==str2);//true
注意,我們這里并不用str1.equals(st⑵;的方式,因?yàn)檫@將比較兩個(gè)字符串的值是否相等。
==號(hào),根據(jù)JDK的說(shuō)明,只有在兩個(gè)引用都指向了同一個(gè)對(duì)象時(shí)才返回真值。而我們?cè)谶@
里要看的是,str1與str2是否都指向了同一個(gè)對(duì)象。
結(jié)果說(shuō)明,JVM創(chuàng)建了兩個(gè)引用str1和str2,但只創(chuàng)建了一個(gè)對(duì)象,而且兩個(gè)引用都指向
了這個(gè)對(duì)象。
我們?cè)賮?lái)更進(jìn)一步,將以上代碼改成:
Stringstr1="abc";
Stringstr2="abc";
str1="bed";
System.out.println(str1++str2);//bed,abe
System.out.println(str1==str2);//false
這就是說(shuō),賦值的變化導(dǎo)致了類(lèi)對(duì)象引用的變化,str1指向了另外一個(gè)新對(duì)象!而str2仍
舊指向原來(lái)的對(duì)象。上例中,當(dāng)我們將str1的值改為"bed"時(shí),JVM發(fā)現(xiàn)在棧中沒(méi)有存放該
值的地址,便開(kāi)辟了這個(gè)地址,并創(chuàng)建了一個(gè)新的對(duì)象,其字符串的值指向這個(gè)地址。
事實(shí)上,String類(lèi)被設(shè)計(jì)成為不可改變(immutable)的類(lèi)。如果你要改變其值,可以,但JVM
在運(yùn)行時(shí)根據(jù)新值悄悄創(chuàng)建了一個(gè)新對(duì)象,然后將這個(gè)對(duì)象的地址返回給原來(lái)類(lèi)的引用。這
個(gè)創(chuàng)建過(guò)程雖說(shuō)是完全自動(dòng)進(jìn)行的,但它畢竟占用了更多的時(shí)間。在對(duì)時(shí)間要求比較敏感的
環(huán)境中,會(huì)帶有一定的不良影響。
再修改原來(lái)代碼:
Stringstr1=HabcH;
Stringstr2="abc";
str1="bed”;
Stringstr3=str1;
System.out.println(str3);//bed
Stringstr4="bed”;
System.out.println(str1==str4);//true
str3這個(gè)對(duì)象的引用直接指向str1所指向的對(duì)象(注意,str3并沒(méi)有創(chuàng)建新對(duì)象)。當(dāng)str1改
完其值后,再創(chuàng)建一個(gè)String的引用str4,并指向因str1修改值而創(chuàng)建的新的對(duì)象。可以
發(fā)現(xiàn),這回str4也沒(méi)有創(chuàng)建新的對(duì)象,從而再次實(shí)現(xiàn)棧中數(shù)據(jù)的共享。
我們?cè)俳又匆韵碌拇a。
Stringstr1=newString("abc");
Stringstr2="abc";
System.out.println(str1==str2);//false
創(chuàng)建了兩個(gè)引用。創(chuàng)建了兩個(gè)對(duì)象。兩個(gè)引用分別指向不同的兩個(gè)對(duì)象。
Stringstr1="abc";
Stringstr2=newString("abc");
System.out.println(str1==str2);//false
創(chuàng)建了兩個(gè)引用。創(chuàng)建了兩個(gè)對(duì)象。兩個(gè)引用分別指向不同的兩個(gè)對(duì)象。
以上兩段代碼說(shuō)明,只要是用new()來(lái)新建對(duì)象的,都會(huì)在堆中創(chuàng)建,而且其字符串是單獨(dú)
存值的,即使可棧中的數(shù)據(jù)相同,也不會(huì)與棧中的數(shù)據(jù)共享。
6.數(shù)據(jù)類(lèi)型包裝類(lèi)的值不可修改。不僅僅是String類(lèi)的值不可修改,所有的數(shù)據(jù)類(lèi)型包裝
類(lèi)都不能更改其內(nèi)部的值。7.結(jié)論與建議:
⑴我們?cè)谑褂弥T如Stringstr="abc";的格式定義類(lèi)時(shí),總是想當(dāng)然地認(rèn)為,我們創(chuàng)建了
String類(lèi)的對(duì)象str。擔(dān)心陷阱!對(duì)象可能并沒(méi)有被創(chuàng)建!唯一可以肯定的是,指向String
類(lèi)的引用被創(chuàng)建了。至于這個(gè)引用到底是否指向了一個(gè)新的對(duì)象,必須根據(jù)上下文來(lái)考慮,
除非你通過(guò)new()方法來(lái)顯要地創(chuàng)建一個(gè)新的對(duì)象。因此,更為準(zhǔn)確的說(shuō)法是,我們創(chuàng)建了
一個(gè)指向String類(lèi)的對(duì)象的引用變量str,這個(gè)對(duì)象引用變量指向了某個(gè)值為"abc”的String
類(lèi)。清醒地認(rèn)識(shí)到這一點(diǎn)對(duì)排除程序中難以發(fā)現(xiàn)的bug是很有幫助的。
⑵使用Stringstr="abc";的方式,可以在一定程度上提高程序的運(yùn)行速度,因?yàn)镴VM會(huì)
自動(dòng)根據(jù)棧中數(shù)據(jù)的實(shí)際情況來(lái)決定是否有必要?jiǎng)?chuàng)建新對(duì)象。而對(duì)于Stringstr=new
String("abc");的代碼,則一概在堆中創(chuàng)建新對(duì)象,而不管其字符串值是否相等,是否有必
要?jiǎng)?chuàng)建新對(duì)象,從而加重了程序的負(fù)擔(dān)。這個(gè)思想應(yīng)該是享元模式的思想,但JDK的內(nèi)部
在這里實(shí)現(xiàn)是否應(yīng)用了這個(gè)模式,不得而知。
(3)當(dāng)比較包裝類(lèi)里面的數(shù)值是否相等時(shí),用equals。方法;當(dāng)測(cè)試兩個(gè)包裝類(lèi)的引用是否
指向同一個(gè)對(duì)象時(shí),用==。
(4)由于String類(lèi)的immutable性質(zhì),當(dāng)String變量需要經(jīng)常變換其值時(shí),應(yīng)該考慮使用
StringBuffer類(lèi),以提高程序效率。
Java本質(zhì)論之關(guān)于Java棧與堆的思考
原文地址http:〃/edu/ShowArticle.asp?ArticlelD=1539
1.棧(stack)與堆(heap)都是Java用來(lái)在Ram中存放數(shù)據(jù)的地方。與C++不同,Java自動(dòng)
管理?xiàng):投?,程序員不能直接地設(shè)置?;蚨?。
2.棧的優(yōu)勢(shì)是,存取速度比堆要快,僅次于直接位于CPU中的寄存器。但缺點(diǎn)是,存在棧
中的數(shù)據(jù)大小與生存期必須是確定的,缺乏靈活性。另外,棧數(shù)據(jù)可以共享,詳見(jiàn)第3點(diǎn)。
堆的優(yōu)勢(shì)是可以動(dòng)態(tài)地分配內(nèi)存大小,生存期也不必事先告訴編譯器,Java的垃圾收集器
會(huì)自動(dòng)收走這些不再使用的數(shù)據(jù)。但缺點(diǎn)是,由于要在運(yùn)行時(shí)動(dòng)態(tài)分配內(nèi)存,存取速度較慢。
3.Java中的數(shù)據(jù)類(lèi)型有兩種。
一種是基本類(lèi)型(primitivetypes),共有8種,即int,short,long,byte,float,double,boolean,
char(注意,并沒(méi)有string的基本類(lèi)型)。這種類(lèi)型的定義是通過(guò)諸如inta=3;longb=255L;
的形式來(lái)定義的,稱為自動(dòng)變量。值得注意的是,自動(dòng)變量存的是字面值,不是類(lèi)的實(shí)例,
即不是類(lèi)的引用,這里并沒(méi)有類(lèi)的存在。如inta=3;這里的a是一個(gè)指向int類(lèi)型的引用,
指向3這個(gè)字面值。這些字面值的數(shù)據(jù),由于大小可知,生存期可知(這些字面值固定定義
在某個(gè)程序塊里面,程序塊退出后,字段值就消失了),出于追求速度的原因,就存在于棧
中。
另外,棧有一個(gè)很重要的特殊性,就是存在棧中的數(shù)據(jù)可以共享。假設(shè)我們同時(shí)定義:
inta=3;
intb=3;
編譯器先處理inta=3;首先它會(huì)在棧中創(chuàng)建一個(gè)變量為a的引用,然后查找有沒(méi)有字面值
為3的地址,沒(méi)找到,就開(kāi)辟一個(gè)存放3這個(gè)字面值的地址,然后將a指向3的地址。接
著處理intb=3;在創(chuàng)建完b的引用變量后,由于在棧中已經(jīng)有3這個(gè)字面值,便將b直接
指向3的地址。這樣,就出現(xiàn)了a與b同時(shí)均指向3的情況。
特別注意的是,這種字面值的引用與類(lèi)對(duì)象的引用不同。假定兩個(gè)類(lèi)對(duì)象的引用同時(shí)指向一
個(gè)對(duì)象,如果一個(gè)對(duì)象引用變量修改了這個(gè)對(duì)象的內(nèi)部狀態(tài),那么另一個(gè)對(duì)象引用變量也即
刻反映出這個(gè)變化。相反,通過(guò)字面值的引用來(lái)修改其值,不會(huì)導(dǎo)致另一個(gè)指向此字面值的
引用的值也跟著改變的情況。如上例,我們定義完a與b的值后,再令a=4;那么,b不會(huì)
等于4,還是等于3。在編譯器內(nèi)部,遇到a=4;時(shí),它就會(huì)重新搜索棧中是否有4的字面
值,如果沒(méi)有,重新開(kāi)辟地址存放4的值;如果已經(jīng)有了,則直接將a指向這個(gè)地址。因
此a值的改變不會(huì)影響到b的值。
另一種是包裝類(lèi)數(shù)據(jù),如Integer,String,Double等將相應(yīng)的基本數(shù)據(jù)類(lèi)型包裝起來(lái)的類(lèi)。
這些類(lèi)數(shù)據(jù)全部存在于堆中,Java用new()語(yǔ)句來(lái)顯示地告訴編譯器,在運(yùn)行時(shí)才根據(jù)需
要?jiǎng)討B(tài)創(chuàng)建,因此比較靈活?,但缺點(diǎn)是要占用更多的時(shí)間。4.String是一個(gè)特殊的包裝類(lèi)
數(shù)據(jù)。即可以用Stringstr=newString("abc");的形式來(lái)創(chuàng)建,也可以用Stringstr="abc";
的形式來(lái)創(chuàng)建(作為對(duì)比,在JDK5.0之前,你從未見(jiàn)過(guò)Integeri=3;的表達(dá)式,因?yàn)轭?lèi)與
字面值是不能通用的,除了String。而在JDK5.0中,這種表達(dá)式是可以的!因?yàn)榫幾g器在
后臺(tái)進(jìn)行Integeri=newlnteger(3)的轉(zhuǎn)換)。前者是規(guī)范的類(lèi)的創(chuàng)建過(guò)程,即在Java中,
一切都是對(duì)象,而對(duì)象是類(lèi)的實(shí)例,全部通過(guò)new()的形式來(lái)創(chuàng)建。Java中的有些類(lèi),如
DateFormat類(lèi),可以通過(guò)該類(lèi)的getlnstance()方法來(lái)返回一個(gè)新創(chuàng)建的類(lèi),似乎違反了此
原則。其實(shí)不然。該類(lèi)運(yùn)用了單例模式來(lái)返回類(lèi)的實(shí)例,只不過(guò)這個(gè)實(shí)例是在該類(lèi)內(nèi)部通過(guò)
new()來(lái)創(chuàng)建的,而getlnstance()向外部隱藏了此細(xì)節(jié)。那為什么在Stringstr="abc";中,
并沒(méi)有通過(guò)new()來(lái)創(chuàng)建實(shí)例,是不是違反了上述原則?其實(shí)沒(méi)有。
5.關(guān)于Stringstr="abc"的內(nèi)部工作。Java內(nèi)部將此語(yǔ)句轉(zhuǎn)化為以下幾個(gè)步驟:
⑴先定義一個(gè)名為str的對(duì)String類(lèi)的對(duì)象引用變量:Stringstr;
(2)在棧中查找有沒(méi)有存放值為"abc"的地址,如果沒(méi)有,則開(kāi)辟一個(gè)存放字面值為"abc"的地
址,接著創(chuàng)建一個(gè)新的String類(lèi)的對(duì)象o,并將。的字符串值指向這個(gè)地址,而且在棧中這
個(gè)地址旁邊記下這個(gè)引用的對(duì)象。。如果已經(jīng)有了值為"abc"的地址,則查找對(duì)象。,并返回
o的地址。
(3)將str指向?qū)ο髈的地址。
值得注意的是,一般String類(lèi)中字符串值都是直接存值的。但像Stringstr="abc";這種場(chǎng)
合下,其字符串值卻是保存了一個(gè)指向存在棧中數(shù)據(jù)的引用!
為了更好地說(shuō)明這個(gè)問(wèn)題,我們可以通過(guò)以下的幾個(gè)代碼進(jìn)行驗(yàn)證。
Stringstr1="abc";
Stringstr2="abc";
System.out.println(str1==str2);//true
注意,我們這里并不用str1.equals(str2);的方式,因?yàn)檫@將比較兩個(gè)字符串的值是否相等。
==號(hào),根據(jù)JDK的說(shuō)明,只有在兩個(gè)引用都指向了同一個(gè)對(duì)象時(shí)才返回真值。而我們?cè)谶@
里要看的是,str1與str2是否都指向了同個(gè)對(duì)象。
結(jié)果說(shuō)明,JVM創(chuàng)建了兩個(gè)引用str1和str2,但只創(chuàng)建了一個(gè)對(duì)象,而且兩個(gè)引用都指向
了這個(gè)對(duì)象。
我們?cè)賮?lái)更進(jìn)一步,將以上代碼改成:
Stringstr1="abc";
Stringstr2="abc";
str1="bed";
System.out.println(str1++str2);//bed,abc
System.out.println(str1==str2);//false
這就是說(shuō),賦值的變化導(dǎo)致了類(lèi)對(duì)象引用的變化,str1指向了另外一個(gè)新對(duì)象!而str2仍
舊指向原來(lái)的對(duì)象。上例中,當(dāng)我們將str1的值改為"bed"時(shí),JVM發(fā)現(xiàn)在棧中沒(méi)有存放該
值的地址,便開(kāi)辟了這個(gè)地址,并創(chuàng)建了一個(gè)新的對(duì)象,其字符串的值指向這個(gè)地址。
事實(shí)上,String類(lèi)被設(shè)計(jì)成為不可改變(immutable)的類(lèi)。如果你要改變其值,可以,但JVM
在運(yùn)行時(shí)根據(jù)新值悄悄創(chuàng)建了一個(gè)新對(duì)象,然后將這個(gè)對(duì)象的地址返回給原來(lái)類(lèi)的引用。這
個(gè)創(chuàng)建過(guò)程雖說(shuō)是完全自動(dòng)進(jìn)行的,但它畢竟占用了更多的時(shí)間。在對(duì)時(shí)間要求比較敏感的
環(huán)境中,會(huì)帶有一定的不良影響。
再修改原來(lái)代碼:
Stringstr1="abc";
Stringstr2=,'abcH;
str1=“bed”;
Stringstr3=str1;
System.out.println(str3);//bed
Stringstr4="bed”;
System.out.println(str1==str4);//true
str3這個(gè)對(duì)象的引用直接指向str1所指向的對(duì)象(注意,str3并沒(méi)有創(chuàng)建新對(duì)象)。當(dāng)str1改
完其值后,再創(chuàng)建一個(gè)String的引用str4,并指向因str1修改值而創(chuàng)建的新的對(duì)象??梢?/p>
發(fā)現(xiàn),這回str4也沒(méi)有創(chuàng)建新的對(duì)象,從而再次實(shí)現(xiàn)棧中數(shù)據(jù)的共享。
我們?cè)俳又匆韵碌拇a。
Stringstr1=newString("abc");
Stringstr2="abc";
System.out.println(str1==str2);//false
創(chuàng)建了兩個(gè)引用。創(chuàng)建了兩個(gè)對(duì)象。兩個(gè)引用分別指向不同的兩個(gè)對(duì)象。
Stringstr1=,'abcH;
Stringstr2=newString("abc");
System.out.println(str1==str2);//false
創(chuàng)建了兩個(gè)引用。創(chuàng)建了兩個(gè)對(duì)象。兩個(gè)引用分別指向不同的兩個(gè)對(duì)象。
以上兩段代碼說(shuō)明,只要是用new()來(lái)新建對(duì)象的,都會(huì)在堆中創(chuàng)建,而且其字符串是單獨(dú)
存值的,即使與棧中的數(shù)據(jù)相同,也不會(huì)與棧中的數(shù)據(jù)共享。
6.數(shù)據(jù)類(lèi)型包裝類(lèi)的值不可修改。不僅僅是String類(lèi)的值不可修改,所有的數(shù)據(jù)類(lèi)型包裝
類(lèi)都不能更改其內(nèi)部的值。7.結(jié)論與建議:
⑴我們?cè)谑褂弥T如Stringstr="abc";的格式定義類(lèi)時(shí),總是想當(dāng)然地認(rèn)為,我們創(chuàng)建了
String類(lèi)的對(duì)象str。擔(dān)心陷阱!對(duì)象可能并沒(méi)有被創(chuàng)建!唯一可以肯定的是,指向String
類(lèi)的引用被創(chuàng)建了。至于這個(gè)引用到底是否指向了一個(gè)新的對(duì)象,必須根據(jù)上下文來(lái)考慮,
除非你通過(guò)new()方法來(lái)顯要地創(chuàng)建一個(gè)新的對(duì)象。因此,更為準(zhǔn)確的說(shuō)法是,我們創(chuàng)建了
一個(gè)指向String類(lèi)的對(duì)象的引用變量str,這個(gè)對(duì)象引用變量指向了某個(gè)值為"abc"的String
類(lèi)。清醒地認(rèn)識(shí)到這一點(diǎn)對(duì)排除程序中難以發(fā)現(xiàn)的bug是很有幫助的。
⑵使用Stringstr="abc";的方式,可以在一定程度上提高程序的運(yùn)行速度,因?yàn)镴VM會(huì)
自動(dòng)根據(jù)棧中數(shù)據(jù)的實(shí)際情況來(lái)決定是否有必要?jiǎng)?chuàng)建新對(duì)象。而對(duì)于Stringstr=new
String("abc");的代碼,則一概在堆中創(chuàng)建新對(duì)象,而不管其字符串值是否相等,是否有必
要?jiǎng)?chuàng)建新對(duì)象,從而加重了程序的負(fù)擔(dān)。這個(gè)思想應(yīng)該是享元模式的思想,但JDK的內(nèi)部
在這里實(shí)現(xiàn)是否應(yīng)用了這個(gè)模式,不得而知。
⑶當(dāng)比較包裝類(lèi)里面的數(shù)值是否相等時(shí),用equals。方法;當(dāng)測(cè)試兩個(gè)包裝類(lèi)的引用是否
指向同一個(gè)對(duì)象時(shí),用==。
(4)由于String類(lèi)的immutable性質(zhì),當(dāng)String變量需要經(jīng)常變換其值時(shí),應(yīng)該考慮使用
StringBuffer類(lèi),以提高程序效率。
入門(mén)必看的5個(gè)JAVA經(jīng)典實(shí)例
1-個(gè)飼養(yǎng)員給動(dòng)物喂食物的例子體現(xiàn)JAVA中的面向?qū)ο笏枷?,接?抽象類(lèi))的用處
packagecom.softeem.demo;
/**
*@authorleno
*動(dòng)物的接口
*/
interfaceAnimal{
publicvoideat(Foodfood);
)
/**
authorleno
*一種動(dòng)物類(lèi):貓
*/
classCatimplementsAnimal{
publicvoideat(Foodfood){
System.out.println("小貓吃"+food.getName());
)
I
/**
*@authorleno
木?種動(dòng)物類(lèi):狗
*/
classDogimplementsAnimal{
publicvoideat(Foodfood){
System.out.println("小狗啃"+food.getName());
)
}
/**
authorleno
*食物抽象類(lèi)
*/
abstractclassFood(
protectedStringname;
publicStringgetName(){
returnname;
publicvoidsetName(Stringname){
=name;
authorleno
*?種食物類(lèi):魚(yú)
*/
classFishextendsFood{
publicFish(Stringname){
=name;
)
}
/**
*@authorleno
*一種食物類(lèi):骨頭
*/
classBoneextendsFood{
publicBone(Stringname){
=name;
/**
*@authorleno
*飼養(yǎng)員類(lèi)
*
*/
classFeeder(
/**
*飼養(yǎng)員給某種動(dòng)物喂某種食物
*@paramanimal
*@paramfood
*/
publicvoidfeed(Animalanimal,Foodfood){
animal.eat(food);
authorleno
*測(cè)試飼養(yǎng)員給動(dòng)物喂食物
*/
publicclassTestFeeder{
publicstaticvoidmain(String[]args){
Feederfeeder=newFeeder();
Animalanimal=newDog();
Foodfood=newBone("肉骨頭)
feeder.fecdfanimal.food);〃給狗喂肉骨頭
animal=newCat();
food=newFish("魚(yú)”);
feeder.feed(animal,food);〃給貓喂魚(yú)
}
}
2.做一個(gè)單子模式的類(lèi),只加載一次屬性文件
packagecom.softeem.demo;
importjava.io.FilelnputStream;
importjava.io.FileNotFoundException:
importjava.io.IOExccption;
importjava.io.InputStream;
importjava.util.Properties;
/**
*@authorleno單子模式,保證在整個(gè)應(yīng)用期間只加載一次配置屬性文件
*/
publicclassSingleton{
privatestaticSingletoninstance;
privatestaticfinalStringCONFIG_FILE_PATH="E:\\perties'1;
privatePropertiesconfig;
privateSingleton(){
config=newProperties();
InputStreamis;
try(
is=newFileInputStream(CONFIG_FILE_PATH);
config.load(is);
is.close();
}catch(FileNotFoundExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}catch(lOExceptione){
//TODOAuto-generatcdcatchblock
e.printStackTrace();
1
)
publicstaticSingletongctlnstance(){
if(instance==null){
instance=newSingleton();
)
returninstance;
publicPropertiesgetConfigO{
returnconfig;
)
publicvoidsetConfig(Propertiesconfig){
this.config=config;
)
1
3.用JAVA中的多線程示例銀行取款問(wèn)題
packagecom.softeem.demo;
/**
*@authorleno
*賬戶類(lèi)
*默認(rèn)有余額,可以取款
*/
classAccount{
privatefloatbalance=1000;
publicfloatgetBalance(){
returnbalance;
)
publicvoidsetBalance(floatbalance){
this.balance=balance;
/**
*取款的方法需要同步
*@parammoney
*/
publicsynchronizedvoidwithdrawals(floatmoney){
if(balance>=money){
System.out.printin("被取走"+money+"元!");
try(
Thread.sleep(1000);
}catch(InterruptedExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
)
balance-=money;
)else{
System.out.println("對(duì)不起,余額不足!)
authorleno
銀行卡
*/
classTestAccount1extendsThread{
privateAccountaccount;
publicTestAccount1(Accountaccount){
this.account=account;
}
@Override
publicvoidrun(){
account.withdrawals(800);
System.out.println("余額為:"+account.getBalance()+"元!”);
*@authorleno
*存折
*/
classTestAccount?extendsThread{
privateAccountaccount;
publicTestAccount2(Accountaccount){
this.account=account;
@Override
publicvoidrun(){
account.withdrawals(700);
System.out.println("余額為:"+account.getBalance()+"元!”);
}
I
publicclassTest{
publicstaticvoidmain(String|]args){
Accountaccount=newAccount();
TestAccountltestAccount1=newTestAccount1(account);
testAccount1.start();
TestAccount2testAccount2=newTestAccount2(account);
testAccount2.starl();
)
)
4.用JAVA中的多線程示例生產(chǎn)者和消費(fèi)者問(wèn)題
packagecom.softeem.demo;
classProducerimplementsRunnable{
privateSyncStackstack;
publicProducer(SyncStackstack){
this.stack=stack;
publicvoidrun(){
for(inti=0;i<stack.getProducts().length;i++){
Stringproduct="產(chǎn)品"+i;
stack.push(product)
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 工作總結(jié)之大專生畢業(yè)總結(jié)報(bào)告
- 2024年加油站項(xiàng)目資金需求報(bào)告代可行性研究報(bào)告
- 2024年體外及體內(nèi)反搏裝置項(xiàng)目資金申請(qǐng)報(bào)告
- 銀行合規(guī)審查制度
- 《支配權(quán)與請(qǐng)求權(quán)》課件
- 《保險(xiǎn)經(jīng)紀(jì)人概況》課件
- 美術(shù)老師工作總結(jié)
- 特別評(píng)論:如何看待退平臺(tái)后企業(yè)與政府的關(guān)系,202412 -中誠(chéng)信
- 山西省臨汾市洪洞縣八校聯(lián)考2023-2024學(xué)年七年級(jí)上學(xué)期期末測(cè)試數(shù)學(xué)試卷(含解析)
- 八年級(jí)物理功率課件
- NY 5051-2001無(wú)公害食品淡水養(yǎng)殖用水水質(zhì)
- GB/T 70.1-2008內(nèi)六角圓柱頭螺釘
- 第一章數(shù)學(xué)的萌芽
- GB/T 24628-2009醫(yī)療保健產(chǎn)品滅菌生物與化學(xué)指示物測(cè)試設(shè)備
- GB/T 24176-2009金屬材料疲勞試驗(yàn)數(shù)據(jù)統(tǒng)計(jì)方案與分析方法
- 四年級(jí)數(shù)學(xué)期末考試質(zhì)量分析
- 多發(fā)性骨髓瘤的療效評(píng)估
- 中建二局“大商務(wù)”管理實(shí)施方案20200713(終稿)
- 導(dǎo)視系統(tǒng)設(shè)計(jì)講解課件
- 新人教部編版六年級(jí)語(yǔ)文上冊(cè)第六單元復(fù)習(xí)課件(含期末復(fù)習(xí)計(jì)劃)
- 燃?xì)獍踩^續(xù)教育考試題及答案
評(píng)論
0/150
提交評(píng)論