JAVA重難點(diǎn)問(wèn)題剖析-實(shí)例講解好理解_第1頁(yè)
JAVA重難點(diǎn)問(wèn)題剖析-實(shí)例講解好理解_第2頁(yè)
JAVA重難點(diǎn)問(wèn)題剖析-實(shí)例講解好理解_第3頁(yè)
JAVA重難點(diǎn)問(wèn)題剖析-實(shí)例講解好理解_第4頁(yè)
JAVA重難點(diǎn)問(wèn)題剖析-實(shí)例講解好理解_第5頁(yè)
已閱讀5頁(yè),還剩37頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(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ì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論