最新java編程思想內(nèi)容(五篇)
范文為教學(xué)中作為模范的文章,也常常用來(lái)指寫(xiě)作的模板。常常用于文秘寫(xiě)作的參考,也可以作為演講材料編寫(xiě)前的參考。范文怎么寫(xiě)才能發(fā)揮它最大的作用呢?以下是我為大家搜集的優(yōu)質(zhì)范文,僅供參考,一起來(lái)看看吧
java編程思想內(nèi)容篇一
計(jì)算器
班級(jí):****** 姓名:******
學(xué)號(hào): ******* 指導(dǎo)老師:******
實(shí)驗(yàn)名稱(chēng):java計(jì)算器
1實(shí)驗(yàn)?zāi)康? java編程語(yǔ)言在編程方面的具體應(yīng)用,以及使用面向?qū)ο蠓椒?對(duì)小應(yīng)用程序進(jìn)行需求分
析、概要設(shè)計(jì)、詳細(xì)設(shè)計(jì),最后使用java編程實(shí)現(xiàn)的全過(guò)程。
2實(shí)驗(yàn)意義:
在編程我們使用的java語(yǔ)言,是目前比較流行的編程語(yǔ)言。在當(dāng)今這個(gè)時(shí)代,java語(yǔ)言在編程方面的優(yōu)勢(shì)使得編程有了更好的選擇。java語(yǔ)言最大的特點(diǎn)是具有跨平臺(tái)性,使其不受平臺(tái)不同的影響,得到了廣泛的應(yīng)用。實(shí)訓(xùn)性質(zhì)
本課程是計(jì)算機(jī)信息管理專(zhuān)業(yè)的一門(mén)實(shí)踐性課程,是《java編程》課程的實(shí)踐性教學(xué)環(huán)節(jié)。實(shí)訓(xùn)目標(biāo)
⑴綜合應(yīng)用java程序設(shè)計(jì)的知識(shí)解決實(shí)際問(wèn)題。
⑵學(xué)會(huì)在應(yīng)用程序的設(shè)計(jì)過(guò)程中,應(yīng)用面向?qū)ο蟮某绦蛟O(shè)計(jì)方法。⑶學(xué)會(huì)應(yīng)用jdbc創(chuàng)建數(shù)據(jù)庫(kù)應(yīng)用程序。
⑷學(xué)會(huì)開(kāi)發(fā)基于swing的應(yīng)用程序及多文檔應(yīng)用程序的設(shè)計(jì)。實(shí)訓(xùn)任務(wù)
用java語(yǔ)言開(kāi)發(fā)工具(例如jdk、jcreator、netbeans等)制作一個(gè)簡(jiǎn)單的可運(yùn)行的完整的應(yīng)用程序或小型系統(tǒng),并編制出各階段必要的文檔。
將創(chuàng)建一個(gè)計(jì)算器,可以進(jìn)行常用的加減乘除算術(shù)運(yùn)算。本實(shí)例的知識(shí)點(diǎn)有:窗口布局器gridlayout的應(yīng)用,對(duì)按鈕消息的監(jiān)聽(tīng)和響應(yīng)。
6實(shí)訓(xùn)條件
<軟件:>windows xp,netbeans ide 6.52 7開(kāi)發(fā)背景: java是由sun microsystems公司于1995年5月推出的java程序設(shè)計(jì)語(yǔ)言(以下簡(jiǎn)稱(chēng)java語(yǔ)言)和java平臺(tái)的總稱(chēng)。java語(yǔ)言是一個(gè)支持網(wǎng)絡(luò)計(jì)算的面向?qū)ο蟪绦蛟O(shè)計(jì)語(yǔ)言。java語(yǔ)言吸收了smalltalk語(yǔ)言和c++語(yǔ)言的優(yōu)點(diǎn),并增加了其它特性,如支持并發(fā)程序設(shè)計(jì)、網(wǎng)絡(luò)通信、和多媒體數(shù)據(jù)控制等。
8系統(tǒng)部分分析:
1)java語(yǔ)言是簡(jiǎn)單的。java語(yǔ)言的語(yǔ)法與c語(yǔ)言和c++語(yǔ)言很接近,使得大多數(shù)程序員很容易學(xué)習(xí)和使用java。另一方面,java丟棄了c++ 中很少使用的、很難理解的、令人迷惑的那些特性,如操作符重載、多繼承、自動(dòng)的強(qiáng)制類(lèi)型轉(zhuǎn)換。
2)java語(yǔ)言是一個(gè)面向?qū)ο蟮。java語(yǔ)言提供類(lèi)、接口和繼承等原語(yǔ),為了簡(jiǎn)單起見(jiàn),只支持類(lèi)之間的單繼承,但支持接口之間的多繼承,并支持類(lèi)與接口之間的實(shí)現(xiàn)機(jī)制(關(guān)鍵字為implements)。java語(yǔ)言全面支持動(dòng)態(tài)綁定,而c++ 語(yǔ)言只對(duì)虛函數(shù)使用動(dòng)態(tài)綁定
3)java語(yǔ)言是分布式的。java語(yǔ)言支持internet應(yīng)用的開(kāi)發(fā),在基本的java應(yīng)用編程接口中有一個(gè)網(wǎng)絡(luò)應(yīng)用編程接口(),它提供了用于網(wǎng)絡(luò)應(yīng)用編程的類(lèi)庫(kù),包括url、urlconnection、socket、serversocket等。java的rmi(遠(yuǎn)程方法激活)機(jī)制也是開(kāi)發(fā)分布式應(yīng)用的重要手段。
4)java語(yǔ)言是健壯的。java的強(qiáng)類(lèi)型機(jī)制、異常處理、廢料的自動(dòng)收集等是java程序健壯性的重要保證。對(duì)指針的丟棄是java的明智選擇。java的安全檢查機(jī)制使得java更具健壯性。
5)java語(yǔ)言是安全的。java通常被用在網(wǎng)絡(luò)環(huán)境中,為此,java提供了一個(gè)安全機(jī)制以防惡意代碼的攻擊。除了java語(yǔ)言具有的許多安全特性以外,java對(duì)通過(guò)網(wǎng)絡(luò)下載的類(lèi)具有一個(gè)安全防范機(jī)制(類(lèi)classloader),如分配不同的名字空間以防替代本地的同名類(lèi)、字節(jié)代碼檢查,并提供安全管理機(jī)制.6)java語(yǔ)言是體系結(jié)構(gòu)中立的。java程序(后綴為java的文件)在java平臺(tái)上被編譯為體系結(jié)構(gòu)中立的字節(jié)碼格式(后綴為class的文件), 然后可以在實(shí)現(xiàn)這個(gè)java平臺(tái)的任何系統(tǒng)中運(yùn)行。
7)java語(yǔ)言是可移植的。這種可移植性來(lái)源于體系結(jié)構(gòu)中立性,另外,java還嚴(yán)格規(guī)定了各個(gè)基本數(shù)據(jù)類(lèi)型的長(zhǎng)度。java系統(tǒng)本身也具有很強(qiáng)的可移植性,java編譯器是用java實(shí)現(xiàn)的.8)java語(yǔ)言是解釋型的。如前所述,java程序在java平臺(tái)上被編譯為字節(jié)碼格式,然后可以在實(shí)現(xiàn)這個(gè)java平臺(tái)的任何系統(tǒng)中運(yùn)行。
9)java是高性能的。與那些解釋型的高級(jí)腳本語(yǔ)言相比,java的確是高性能的。事實(shí)上,java的運(yùn)行速度隨著jit(just-in-time)編譯器技術(shù)的發(fā)展越來(lái)越接近于c++。
10)java語(yǔ)言是多線(xiàn)程的。在java語(yǔ)言中,線(xiàn)程是一種特殊的對(duì)象,它必須由thread類(lèi)或其子(孫)類(lèi)來(lái)創(chuàng)建。
11)java語(yǔ)言是動(dòng)態(tài)的。java語(yǔ)言的設(shè)計(jì)目標(biāo)之一是適應(yīng)于動(dòng)態(tài)變化的環(huán)境。
目錄
課程設(shè)計(jì)題目 ……………………………… p1
課程設(shè)計(jì)簡(jiǎn)介 ……………………………… p2
課程設(shè)計(jì)源代碼…………………………… p5
課程設(shè)計(jì)運(yùn)行結(jié)果 ……………………… p15 課程設(shè)計(jì)心得體會(huì) ………………………
p16
package computerpad;import .*;import .event.*;import .*;import .*;import list;import format;public class computerpad extends frame implements actionlistener {
numberbutton numberbutton[];
operationbutton oprationbutton[];
button 小數(shù)點(diǎn)按鈕,正負(fù)號(hào)按鈕,退格按鈕,求倒數(shù)按鈕,等號(hào)按鈕,清零按鈕;
panel panel;
jtextfield resultshow;
string 運(yùn)算符號(hào)[]={“+”,“-”,“*”,“/”};
linkedlist 鏈表;
boolean 是否按下等號(hào)=false;
public computerpad()
{
super(“計(jì)算器”);
鏈表=new linkedlist();
numberbutton=new numberbutton[10];
for(int i=0;i<=9;i++)
{
numberbutton[i]=new numberbutton(i);
numberbutton[i].addactionlistener(this);
}
oprationbutton=new operationbutton[4];
for(int i=0;i<4;i++)
{
oprationbutton[i]=new operationbutton(運(yùn)算符號(hào)[i]);
oprationbutton[i].addactionlistener(this);
}
小數(shù)點(diǎn)按鈕=new button(“.”);
正負(fù)號(hào)按鈕
=new button(“+/-”);
等號(hào)按鈕=new button(“=”);
求倒數(shù)按鈕=new button(“1/x”);
退格按鈕=new button(“退格”);
清零按鈕=new button(“c”);
eground();
eground();
eground();
eground();
eground();
eground();
ionlistener(this);
ionlistener(this);
ionlistener(this);
ionlistener(this);
ionlistener(this);
ionlistener(this);
resultshow=new jtextfield(10);
izontalalignment();
eground();
t(new font(“timesroman”,,14));
der(new softbevelborder(d));
kground();
table(false);
panel=new panel();
out(new gridlayout(4,5));
(numberbutton[1]);
(numberbutton[2]);
(numberbutton[3]);
(oprationbutton[0]);
(清零按鈕);
(numberbutton[4]);
(numberbutton[5]);
(numberbutton[6]);
(oprationbutton[1]);
(退格按鈕);
(numberbutton[7]);
(numberbutton[8]);
(numberbutton[9]);
(oprationbutton[2]);
(求倒數(shù)按鈕);
(numberbutton[0]);
(正負(fù)號(hào)按鈕);
(小數(shù)點(diǎn)按鈕);
(oprationbutton[3]);
(等號(hào)按鈕);
add(panel,);
add(resultshow,);
addwindowlistener(new windowadapter()
{ public void windowclosing(windowevent e)
{
(0);
}
});
setvisible(true);
setbounds(100,50,240,180);
setresizable(false);
validate();
} public void actionperformed(actionevent e)
{
if(rce()instanceof numberbutton)
{
numberbutton b=(numberbutton)rce();
if(()==0)
{
int number=ber();
(“"+number);
t(”“+number);
是否按下等號(hào)=false;
}
else if(()==1&&是否按下等號(hào)==false)
{
int number=ber();
string num=(string)first();
string s=(”“+number);
(0,s);
t(s);
}
else if(()==1&&是否按下等號(hào)==true)
{
int number=ber();
first();
(”“+number);
是否按下等號(hào)=false;
t(”“+number);
}
else if(()==2)
{
int number=ber();
(”“+number);
t(”“+number);
}
else if(()==3)
{
int number=ber();
string num=(string)t();
string s=(”“+number);
(2,s);
t(s);
}
}
else if(rce()instanceof operationbutton)
{
operationbutton b=(operationbutton)rce();
if(()==1)
{
string fuhao=運(yùn)算符號(hào)();
(fuhao);
}
else if(()==2)
{
string fuhao=運(yùn)算符號(hào)();
(1,fuhao);
}
else if(()==3)
{
string fuhao=運(yùn)算符號(hào)();
string number1=(string)first();
string number2=(string)t();
string 運(yùn)算符號(hào)=(string)(1);
try
{
double n1=ouble(number1);
double n2=ouble(number2);
double n=0;
if((”+“))
{
n=n1+n2;
}
else if((”-“))
{
n=n1-n2;
}
else if((”*“))
{
n=n1*n2;
}
else if((”/“))
{
n=n1/n2;
}
();
(”“+n);
(fuhao);
t(”“+n);
}
catch(exception ee)
{
}
}
}
else if(rce()==等號(hào)按鈕)
{
是否按下等號(hào)=true;
if(()==1||()==2)
{
string num=(string)first();
t(”“+num);
}
else if(()==3)
{
string number1=(string)first();
string number2=(string)t();
string 運(yùn)算符號(hào)=(string)(1);
try
{
double n1=ouble(number1);
double n2=ouble(number2);
double n=0;
if((”+“))
{
n=n1+n2;
}
else if((”-“))
{
n=n1-n2;
}
else if((”*“))
{
n=n1*n2;
}
else if((”/“))
{
n=n1/n2;
}
t(”“+n);
(0,”“+n);
last();
last();
}
catch(exception ee)
{
}
}
}
else if(rce()==小數(shù)點(diǎn)按鈕)
{
if(()==0)
{
是否按下等號(hào)=false;
}
else if(()==1)
{
string dot=el();
string num=(string)first();
string s=null;
if(f(dot)==-1)
{
s=(dot);
(0,s);
}
else
{
s=num;
}
(0,s);
t(s);
}
else if(()==3)
{
string dot=el();
string num=(string)t();
string s=null;
if(f(dot)==-1)
{
s=(dot);
(2,s);
}
else
{
s=num;
}
t(s);
}
}
else if(rce()==退格按鈕)
{
if(()==1)
{
string num=(string)first();
if(()>=1)
{
num=ing(0,()-1);
(0,num);
t(num);
}
else
{
last();
t(”0“);
}
}
else if(()==3)
{
string num=(string)t();
if(()>=1)
{ num=ing(0,()-1);
(2,num);
t(num);
}
else
{
last();
t(”0“);
}
}
}
else if(rce()==正負(fù)號(hào)按鈕)
{
if(()==1)
{
string number1=(string)first();
try
{
double d=ouble(number1);
d=-1*d;
string str=f(d);
(0,str);
t(str);
}
catch(exception ee)
{
}
}
else if(()==3)
{
string number2=(string)t();
try
{
double d=ouble(number2);
d=-1*d;
string str=f(d);
(2,str);
t(str);
}
catch(exception ee){
}
}
}
else if(rce()==求倒數(shù)按鈕)
{
if(()==1||()==2)
{
string number1=(string)first();
try
{
double d=ouble(number1);
d=1.0/d;
string str=f(d);
(0,str);
t(str);
}
catch(exception ee){
}
}
else if(()==3)
{
string number2=(string)t();
try
{
double d=ouble(number2);
d=1.0/d;
string str=f(d);
(0,str);
t(str);
}
catch(exception ee){
}
}
}
else if(rce()==清零按鈕)
{
是否按下等號(hào)=false;
t(”0“);
();
}
} public static void main(string args[])
{
new computerpad();
}
}
package computerpad;import .*;import .event.*;import .*;public class numberbutton extends button {
int number;
public numberbutton(int number)
{
super(”"+number);
=number;
setforeground();
}
public int getnumber()
{
return number;
} }
import .*;import .event.*;import .*;public class operationbutton extends button {
string 運(yùn)算符號(hào);
public operationbutton(string s)
{
super(s);
運(yùn)算符號(hào)=s;
setforeground();
}
public string get運(yùn)算符號(hào)()
{
return 運(yùn)算符號(hào);
} } 14 java實(shí)訓(xùn)心得:
未接觸java之前,聽(tīng)人說(shuō)java這門(mén)語(yǔ)言如何的強(qiáng)大和難以入門(mén),但學(xué)習(xí)之后,給我的感覺(jué)卻是語(yǔ)言沒(méi)有所謂的難于不難,關(guān)鍵是自己有沒(méi)有真正投入去學(xué),有沒(méi)有花時(shí)間去學(xué)。java是一門(mén)很好的語(yǔ)言,經(jīng)過(guò)周?chē)藢?duì)java的宣傳,我一開(kāi)始不敢去學(xué)習(xí)這門(mén)語(yǔ)言,因?yàn)橐婚T(mén)高級(jí)語(yǔ)言總是讓人想到一開(kāi)始的學(xué)習(xí)會(huì)很難,但是后來(lái)在自己的努力和老師同學(xué)的幫助下,我加入了java學(xué)習(xí)者的行列。
老師把我們帶進(jìn)了門(mén),那么,以后漫長(zhǎng)的深入學(xué)習(xí)還是要靠自己。經(jīng)常性的編寫(xiě)一些程序,或則去看懂、研究透別人編寫(xiě)的程序?qū)τ谖覀兇蚝没A(chǔ)是非常有利的。讓我們懷著對(duì)java的一腔熱情,用自己的刻苦努力去把java學(xué)好。將來(lái),用自己的成績(jī)?nèi)セ貓?bào)有恩于我們的社會(huì)、家人和朋友。
java編程思想內(nèi)容篇二
java編程思想,java學(xué)習(xí)必讀經(jīng)典,不管是初學(xué)者還是大牛都值得一讀,這里總結(jié)書(shū)中的重點(diǎn)知識(shí),這些知識(shí)不僅經(jīng)常出現(xiàn)在各大知名公司的筆試面試過(guò)程中,而且在大型項(xiàng)目開(kāi)發(fā)中也是常用的知識(shí),既有簡(jiǎn)單的概念理解題(比如is-a關(guān)系和has-a關(guān)系的區(qū)別),也有深入的涉及rtti和jvm底層反編譯知識(shí)。
中的多態(tài)性理解(注意與c++區(qū)分)
? java中除了static方法和final方法(private方法本質(zhì)上屬于final方法,因?yàn)椴荒鼙蛔宇?lèi)訪(fǎng)問(wèn))之外,其它所有的方法都是動(dòng)態(tài)綁定,這意味著通常情況下,我們不必判定是否應(yīng)該進(jìn)行動(dòng)態(tài)綁定—它會(huì)自動(dòng)發(fā)生。? final方法會(huì)使編譯器生成更有效的代碼,這也是為什么說(shuō)聲明為final方法能在一定程度上提高性能(效果不明顯)。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 如果某個(gè)方法是靜態(tài)的,它的行為就不具有多態(tài)性:
class staticsuper {
public static string staticget(){
return “base staticget()”;
}
public string dynamicget(){
return “base dynamicget()”;
} }
class staticsub extends staticsuper {
public static string staticget(){
return “derived staticget()”;
}
public string dynamicget(){
return “derived dynamicget()”;
} }
public class staticpolymorphism {
public static void main(string[] args){ staticsuper sup = new staticsub();.println(get());.println(cget());
}
}
輸出:
base staticget()derived dynamicget()? 構(gòu)造函數(shù)并不具有多態(tài)性,它們實(shí)際上是static方法,只不過(guò)該static聲明是隱式的。因此,構(gòu)造函數(shù)不能夠被override。
? 在父類(lèi)構(gòu)造函數(shù)內(nèi)部調(diào)用具有多態(tài)行為的函數(shù)將導(dǎo)致無(wú)法預(yù)測(cè)的結(jié)果,因?yàn)榇藭r(shí)子類(lèi)對(duì)象還沒(méi)初始化,此時(shí)調(diào)用子類(lèi)方法不會(huì)得到我們想要的結(jié)果。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? class glyph {
void draw(){
.println(“()”);
}
glyph(){
.println(“glyph()before draw()”);draw();
.println(“glyph()after draw()”);
} }
class roundglyph extends glyph {
private int radius = 1;
roundglyph(int r){ radius = r;
.println(“l(fā)yph().radius = ” + radius);
}
void draw(){
.println(“round().radius = ” + radius);
} }
public class polyconstructors {
public static void main(string[] args){
new roundglyph(5);
}
}
輸出: glyph()before draw()round().radius = 0 glyph()after draw()lyph().radius = 5 為什么會(huì)這樣輸出?這就要明確掌握java中構(gòu)造函數(shù)的調(diào)用順序:
(1)在其他任何事物發(fā)生之前,將分配給對(duì)象的存儲(chǔ)空間初始化成二進(jìn)制0;
(2)調(diào)用基類(lèi)構(gòu)造函數(shù)。從根開(kāi)始遞歸下去,因?yàn)槎鄳B(tài)性此時(shí)調(diào)用子類(lèi)覆蓋后的draw()方法(要在調(diào)用roundglyph構(gòu)造函數(shù)之前調(diào)用),由于步驟1的緣故,我們此時(shí)會(huì)發(fā)現(xiàn)radius的值為0;
(3)按聲明順序調(diào)用成員的初始化方法;(4)最后調(diào)用子類(lèi)的構(gòu)造函數(shù)。
? 只有非private方法才可以被覆蓋,但是還需要密切注意覆蓋private方法的現(xiàn)象,這時(shí)雖然編譯器不會(huì)報(bào)錯(cuò),但是也不會(huì)按照我們所期望的來(lái)執(zhí)行,即覆蓋private方法對(duì)子類(lèi)來(lái)說(shuō)是一個(gè)新的方法而非重載方法。因此,在子類(lèi)中,新方法名最好不要與基類(lèi)的private方法采取同一名字(雖然沒(méi)關(guān)系,但容易誤解,以為能夠覆蓋基類(lèi)的private方法)。
? java類(lèi)中屬性域的訪(fǎng)問(wèn)操作都由編譯器解析,因此不是多態(tài)的。父類(lèi)和子類(lèi)的同名屬性都會(huì)分配不同的存儲(chǔ)空間,如下:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // direct field access is determined at compile super {
public int field = 0;
public int getfield(){
return field;
} }
class sub extends super {
public int field = 1;
public int getfield(){
return field;
}
public int getsuperfield(){
return ;
} }
public class fieldaccess {
public static void main(string[] args){ super sup = new sub();
.println(“ = ” + +
“, ld()= ” + ld());sub sub = new sub();
.println(“ = ” + + ? ? ? ? ? “, ld()= ” + ld()+ “, erfield()= ” + erfield());
}
}
輸出:
= 0, ld()= 1 = 1, ld()= 1, erfield()= 0 sub子類(lèi)實(shí)際上包含了兩個(gè)稱(chēng)為field的域,然而在引用sub中的field時(shí)所產(chǎn)生的默認(rèn)域并非super版本的field域,因此為了得到,必須顯式地指明。
-a關(guān)系和is-like-a關(guān)系
? is-a關(guān)系屬于純繼承,即只有在基類(lèi)中已經(jīng)建立的方法才可以在子類(lèi)中被覆蓋,如下圖所示:
基類(lèi)和子類(lèi)有著完全相同的接口,這樣向上轉(zhuǎn)型時(shí)永遠(yuǎn)不需要知道正在處理的對(duì)象的確切類(lèi)型,這通過(guò)多態(tài)來(lái)實(shí)現(xiàn)。
? is-like-a關(guān)系:子類(lèi)擴(kuò)展了基類(lèi)接口。它有著相同的基本接口,但是他還具有由額外方法實(shí)現(xiàn)的其他特性。
缺點(diǎn)就是子類(lèi)中接口的擴(kuò)展部分不能被基類(lèi)訪(fǎng)問(wèn),因此一旦向上轉(zhuǎn)型,就不能調(diào)用那些新方法。
3.運(yùn)行時(shí)類(lèi)型信息(rtti + 反射)
? 概念
rtti:運(yùn)行時(shí)類(lèi)型信息使得你可以在程序運(yùn)行時(shí)發(fā)現(xiàn)和使用類(lèi)型信息。? 使用方式
java是如何讓我們?cè)谶\(yùn)行時(shí)識(shí)別對(duì)象和類(lèi)的信息的,主要有兩種方式(還有輔助的第三種方式,見(jiàn)下描述): ? 一種是“傳統(tǒng)的”rtti,它假定我們?cè)诰幾g時(shí)已經(jīng)知道了所有的類(lèi)型,比如shape s =(shape)s1; ? 另一種是“反射”機(jī)制,它運(yùn)行我們?cè)谶\(yùn)行時(shí)發(fā)現(xiàn)和使用類(lèi)的信息,e()。
? 其實(shí)還有第三種形式,就是關(guān)鍵字instanceof,它返回一個(gè)bool值,它保持了類(lèi)型的概念,它指的是“你是這個(gè)類(lèi)嗎?或者你是這個(gè)類(lèi)的派生類(lèi)嗎?”。而如果用==或equals比較實(shí)際的class對(duì)象,就沒(méi)有考慮繼承—它或者是這個(gè)確切的類(lèi)型,或者不是。
? 工作原理
要理解rtti在java中的工作原理,首先必須知道類(lèi)型信息在運(yùn)行時(shí)是如何表示的,這項(xiàng)工作是由稱(chēng)為class對(duì)象的特殊對(duì)象完成的,它包含了與類(lèi)有關(guān)的信息。java送class對(duì)象來(lái)執(zhí)行其rtti,使用類(lèi)加載器的子系統(tǒng)實(shí)現(xiàn)。
無(wú)論何時(shí),只要你想在運(yùn)行時(shí)使用類(lèi)型信息,就必須首先獲得對(duì)恰當(dāng)?shù)腸lass對(duì)象的引用,獲取方式有三種:
(1)如果你沒(méi)有持有該類(lèi)型的對(duì)象,e()就是實(shí)現(xiàn)此功能的便捷途,因?yàn)樗恍枰獙?duì)象信息;
(2)如果你已經(jīng)擁有了一個(gè)感興趣的類(lèi)型的對(duì)象,那就可以通過(guò)調(diào)用getclass()方法來(lái)獲取class引用了,它將返回表示該對(duì)象的實(shí)際類(lèi)型的class引用。class包含很有有用的方法,比如: package rtti;
interface hasbatteries{} interface waterproof{} interface shoots{}
class toy { toy(){}
toy(int i){} }
class fancytoy extends toy implements hasbatteries, waterproof, shoots { fancytoy(){
super(1);
} }
public class rttitest {
static void printinfo(class cc){
.println(“class name: ” + e()+ “, is interface? [” + rface()+ “]”);.println(“simple name: ” + plename());.println(“canonical name: ” + onicalname());
}
public static void main(string[] args){ class c = null;
try {
c = e(“oy”);// 必須是全限定名(包名+類(lèi)名)
} catch(classnotfoundexception e){
.println(“can't find fancytoy”);(1);
}
printinfo(c);
for(class face : erfaces()){ printinfo(face);
}
class up = erclass();object obj = null;
try { // requires default = tance();
} catch(instantiationexception e){
.println(“can't instantiate”);(1);
} catch(illegalaccessexception e){ .println(“can't access”);(1);
}
printinfo(ss());
}
}
輸出:
class name: oy, is interface? [false] simple name: fancytoy canonical name: oy class name: teries, is interface? [true] simple name: hasbatteries canonical name: teries class name: roof, is interface? [true] simple name: waterproof canonical name: roof class name: , is interface? [true] simple name: shoots canonical name: class name: , is interface? [false] simple name: toy canonical name: (3)java還提供了另一種方法來(lái)生成對(duì)class對(duì)象的引用,即使用類(lèi)字面常量。比如上面的就像這樣:;來(lái)引用。
這樣做不僅更簡(jiǎn)單,而且更安全,因?yàn)樗诰幾g時(shí)就會(huì)受到檢查(因此不需要置于try語(yǔ)句塊中),并且它根除了對(duì)forname方法的引用,所以也更高效。類(lèi)字面常量不僅可以應(yīng)用于普通的類(lèi),也可以應(yīng)用于接口、數(shù)組以及基本數(shù)據(jù)類(lèi)型。
注意:當(dāng)使用“.class”來(lái)創(chuàng)建對(duì)class對(duì)象的引用時(shí),不會(huì)自動(dòng)地初始化該class對(duì)象,初始化被延遲到了對(duì)靜態(tài)方法(構(gòu)造器隱式的是靜態(tài)的)或者非final靜態(tài)域(注意final靜態(tài)域不會(huì)觸發(fā)初始化操作)進(jìn)行首次引用時(shí)才執(zhí)行:。而使用e時(shí)會(huì)自動(dòng)的初始化。
為了使用類(lèi)而做的準(zhǔn)備工作實(shí)際包含三個(gè)步驟:
-加載:由類(lèi)加載器執(zhí)行。查找字節(jié)碼,并從這些字節(jié)碼中創(chuàng)建一個(gè)class對(duì)象
-鏈接:驗(yàn)證類(lèi)中的字節(jié)碼,為靜態(tài)域分配存儲(chǔ)空間,并且如果必需的話(huà),將解析這個(gè)類(lèi)創(chuàng)建的對(duì)其他類(lèi)的所有引用。
-初始化:如果該類(lèi)具有超類(lèi),則對(duì)其初始化,執(zhí)行靜態(tài)初始化器和靜態(tài)初始化塊。這一點(diǎn)非常重要,下面通過(guò)一個(gè)實(shí)例來(lái)說(shuō)明這兩者的區(qū)別:
package rtti;
import ;class initable {
static final int staticfinal = 47;
static final int staticfinal2 = t(1000);
static {
.println(“initializing initable”);
} }
class initable2 {
static int staticnonfinal = 147;
static {
.println(“initializing initable2”);
} }
class initable3 {
static int staticnonfinal = 74;
static {
.println(“initializing initable3”);
} }
public class classinitialization {
public static random rand = new random(47);
public static void main(string[] args){
// does not trigger initialization class initable = ;
.println(“after creating initable ref”);
// does not trigger initialization
.println(final);
// does trigger initialization(rand()is static method).println(final2);
// does trigger initialization(not final)
.println(nonfinal);
try {
class initable3 = e(“l(fā)e3”);
} catch(classnotfoundexception e){
.println(“can't find initable3”);(1);
}
.println(“after creating initable3 ref”);.println(nonfinal);
} }
輸出:
after creating initable ref 47 initializing initable 258 initializing initable2 147 initializing initable3 after creating initable3 ref 74
rtti的限制?如何突破? — 反射機(jī)制
如果不知道某個(gè)對(duì)象的確切類(lèi)型,rtti可以告訴你,但是有一個(gè)限制:這個(gè)類(lèi)型在編譯時(shí)必須已知,這樣才能使用rtti識(shí)別它,也就是在編譯時(shí),編譯器必須知道所有要通過(guò)rtti來(lái)處理的類(lèi)。
可以突破這個(gè)限制嗎?是的,突破它的就是反射機(jī)制。
t類(lèi)庫(kù)一起對(duì)反射的概念進(jìn)行了支持,該類(lèi)庫(kù)包含了field、method以及constructor類(lèi)(每個(gè)類(lèi)都實(shí)現(xiàn)了member接口)。這些類(lèi)型的對(duì)?
象是由jvm在運(yùn)行時(shí)創(chuàng)建的,用以表示未知類(lèi)里對(duì)應(yīng)的成員。這樣你就可以使用constructor創(chuàng)建新的對(duì)象,用get()/set()方法讀取和修改與field對(duì)象關(guān)聯(lián)的字段,用invoke()方法調(diào)用與method對(duì)象關(guān)聯(lián)的方法。另外,還可以調(diào)用getfields()、getmethods()和getconstructors()等很便利的方法,以返回表示字段、方法以及構(gòu)造器的對(duì)象的數(shù)組。這樣,匿名對(duì)象的類(lèi)信息就能在運(yùn)行時(shí)被完全確定下來(lái),而在編譯時(shí)不需要知道任何事情。
####反射與rtti的區(qū)別
當(dāng)通過(guò)反射與一個(gè)未知類(lèi)型的對(duì)象打交道時(shí),jvm只是簡(jiǎn)單地檢查這個(gè)對(duì)象,看它屬于哪個(gè)特定的類(lèi)(就像rtti那樣),在用它做其他事情之前必須先加載那個(gè)類(lèi)的class對(duì)象,因此,文件對(duì)于jvm來(lái)說(shuō)必須是可獲取的:要么在本地機(jī)器上,要么可以通過(guò)網(wǎng)絡(luò)取得。所以rtti與反射之間真正的區(qū)別只在于:對(duì)rtti來(lái)說(shuō),文件(也就是可以用普通方法調(diào)用對(duì)象的所有方法);而對(duì)于反射機(jī)制來(lái)說(shuō),.class文件在編譯時(shí)是不可獲取的,文件。下面的例子是用反射機(jī)制打印出一個(gè)類(lèi)的所有方法(包括在基類(lèi)中定義的方法):
package typeinfo;
import uctor;import ;import n;
// using reflection to show all the methods of a class.// even if the methods are defined in the base class showmethods { private static string usage =
“usage: n” +
“showmethods ” +
“to show all methods in class or: n” +
“showmethods wordn” +
“to search for methods involving 'word'”;
private static pattern p = e(“w+.”);
public static void main(string[] args){ if( < 1){ .println(usage);(0);} int lines = 0;try { class<? > c = e(args[0]);method[] methods = hods();constructor[] ctors = structors();if( == 1){ for(method method : methods){
.println(r(ng()).replaceall(“"));} for(constructor ctor : ctors){
.println(r(ng()).replaceall(”“));} lines = + ;} else { for(method method : methods){ if(ng().indexof(args[1])!=-1){
.println(r(ng()).replaceall(”“));lines++;} } for(constructor ctor : ctors){ if(ng().indexof(args[1])!=-1){
.println(r(ng()).replaceall(”“));lines++;} } } } catch(classnotfoundexception e){ .println(”no such class: “ + e);}
} }
輸出:
public static void main(string[])public final native void wait(long)throws interruptedexception public final void wait()throws interruptedexception public final void wait(long,int)throws interruptedexception public boolean equals(object)public string tostring()public native int hashcode()public final native class getclass()public final native void notify()public final native void notifyall()public showmethods()4.代理模式與java中的動(dòng)態(tài)代理
? 代理模式
在任何時(shí)刻,只要你想要將額外的操作從“實(shí)際”對(duì)象中分離到不同的地方,特別是當(dāng)你希望能夠很容易地做出修改,從沒(méi)有使用額外操作轉(zhuǎn)為使用這些操作,或者反過(guò)來(lái)時(shí),代理就顯得很有用(設(shè)計(jì)模式的關(guān)鍵是封裝修改)。例如,如果你希望跟蹤對(duì)某個(gè)類(lèi)中方法的調(diào)用,或者希望度量這些調(diào)用的開(kāi)銷(xiāo),那么你應(yīng)該怎樣做呢?這些代碼肯定是你不希望將其合并到應(yīng)用中的代碼,因此代理使得你可以很容易地添加或移除它們。
? ? ? interface interface {
void dosomething();
void somethingelse(string arg);? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }
class realobject implements interface {
@override public void dosomething(){
.println(”dosomething.“);
}
@override public void somethingelse(string arg){
.println(”somethingelse “ + arg);
} }
class simpleproxy implements interface {
private interface proxy;
public simpleproxy(interface proxy){
= proxy;
}
@override public void dosomething(){
.println(”simpleproxy dosomething.“);thing();
}
@override public void somethingelse(string arg){
.println(”simpleproxy somethingelse “ + arg);
ingelse(arg);
} }
public class simpleproxydemo {
public static void consumer(interface iface){ thing();
ingelse(”bonobo“);
} ? ? ? ? ? ? public static void main(string[] args){ consumer(new realobject());
consumer(new simpleproxy(new realobject()));
}
}
輸出:
ingelse bonobo simpleproxy proxy somethingelse bonobo somethingelse bonobo ? 動(dòng)態(tài)代理
java的動(dòng)態(tài)代理比代理的思想更向前邁進(jìn)了一步,因?yàn)樗梢詣?dòng)態(tài)地創(chuàng)建代理并動(dòng)態(tài)地處理對(duì)所代理方法的調(diào)用。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? import tionhandler;import ;import ;
class dynamicproxyhandler implements invocationhandler {
private object proxy;
public dynamicproxyhandler(object proxy){
= proxy;
}
@override public object invoke(object proxy, method method, object[] args)
throws throwable {
.println(”*** proxy: “ + ss()+
”.method: “ + method + ”.args: “ + args);
if(args!= null){
for(object arg : args)
.println(” “ + arg);
}
return (, args);
} }
public class simpledynamicproxy { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
public static void consumer(interface iface){ thing();
ingelse(”bonobo“);
}
public static void main(string[] args){ realobject real = new realobject();consumer(real);
// insert a proxy and call again:
interface proxy =(interface)xyinstance(.getclassloader(), new class[]{ },new dynamicproxyhandler(real));
consumer(proxy);
}
}
輸出:
ingelse bonobo *** proxy: class typeinfo.$: public abstract void thing().args: null dosomething.*** proxy: class typeinfo.$: public abstract void ingelse().args: [;@6a8814e9 bonobo somethingelse bonobo 5.即時(shí)編譯器技術(shù) — jit java虛擬機(jī)中有許多附加技術(shù)用以提升速度,尤其是與加載器操作相關(guān)的,被稱(chēng)為“即時(shí)”(just-in-time,jit)編譯器的技術(shù)。這種技術(shù)可以把程序全部或部分翻譯成本地機(jī)器碼(這本來(lái)是jvm的工作),程序運(yùn)行速度因此得以提升。當(dāng)需要裝載某個(gè)類(lèi)時(shí),文件,然后將該類(lèi)的字節(jié)碼裝入內(nèi)存。此時(shí),有兩種方案可供選擇:
(1)一種就是讓即時(shí)編譯器編譯所有代碼。但這種做法有兩個(gè)缺陷:這種加載動(dòng)作散落在整個(gè)程序生命周期內(nèi),累加起來(lái)要花更多時(shí)間;并且會(huì)增加可執(zhí)行代碼的長(zhǎng)度(字節(jié)碼要比即時(shí)編譯器展開(kāi)后的本地機(jī)器碼小很多),這將導(dǎo)致頁(yè)面調(diào)度,從而降低程序速度。(2)另一種做法稱(chēng)為惰性評(píng)估(lazy evaluation),意思是即時(shí)編譯器只在必要的時(shí)候才編譯代碼,這樣,從不會(huì)被執(zhí)行的代碼也許就壓根不會(huì)被jit所編譯。新版jdk中的java hotspot技術(shù)就采用了類(lèi)似方法,代碼每次被執(zhí)行的時(shí)候都會(huì)做一些優(yōu)化,所以執(zhí)行的次數(shù)越多,它的速度就越快。
6.訪(fǎng)問(wèn)控制權(quán)限 ? ? java訪(fǎng)問(wèn)權(quán)限修飾詞:public、protected、包訪(fǎng)問(wèn)權(quán)限(默認(rèn)訪(fǎng)問(wèn)權(quán)限,有時(shí)也稱(chēng)friendly)和private。
包訪(fǎng)問(wèn)權(quán)限:當(dāng)前包中的所有其他類(lèi)對(duì)那個(gè)成員具有訪(fǎng)問(wèn)權(quán)限,但對(duì)于這個(gè)包之外的所有類(lèi),這個(gè)成員卻是private。
protected:繼承訪(fǎng)問(wèn)權(quán)限。有時(shí)基類(lèi)的創(chuàng)建者會(huì)希望有某個(gè)特定成員,把對(duì)它的訪(fǎng)問(wèn)權(quán)限賦予派生類(lèi)而不是所有類(lèi)。這就需要protected來(lái)完成這一工作。protected也提供包訪(fǎng)問(wèn)權(quán)限,也就是說(shuō),相同包內(nèi)的其他類(lèi)都可以訪(fǎng)問(wèn)protected元素。protected指明“就類(lèi)用戶(hù)而言,這是private的,但對(duì)于任何繼承于此類(lèi)的導(dǎo)出類(lèi)或其他任何位于同一個(gè)包內(nèi)的類(lèi)來(lái)說(shuō),它卻是可以訪(fǎng)問(wèn)的”。比如: 基類(lèi): ?
? ? ? ? ? ? ? ? ? ? package ;public class cookie {
public cookie(){
.println(”cookie constructor“);
}
void bite(){ // 包訪(fǎng)問(wèn)權(quán)限,其它包即使是子類(lèi)也不能訪(fǎng)問(wèn)它 .println(”bite“);
} }
子類(lèi):
package t;
import .cookie;
public class chocolatechip extends cookie {
public chocolatechip(){
.println(”chocolatechip constructor“);
}
public void chomp(){
bite();// error, the method bite()from the type cookie is not visible
} }
可以發(fā)現(xiàn)子類(lèi)并不能訪(fǎng)問(wèn)基類(lèi)的包訪(fǎng)問(wèn)權(quán)限方法。此時(shí)可以將cookie中的bite指定為public,但這樣做所有的人就都有了訪(fǎng)問(wèn)權(quán)限,為了只允許子類(lèi)訪(fǎng)問(wèn),可以將bite指定為protected即可。
7.組合和繼承之間的選擇
? 組合和繼承都允許在新的類(lèi)中放置子對(duì)象,組合是顯式的這樣做,而繼承則是隱式的做。?
?
? ? 組合技術(shù)通常用于想在新類(lèi)中使用現(xiàn)有類(lèi)的功能而非它的接口這種情形。即在新類(lèi)中嵌入某個(gè)對(duì)象,讓其實(shí)現(xiàn)所需要的功能,但新類(lèi)的用戶(hù)看到的只是為新類(lèi)所定義的接口,而非所嵌入對(duì)象的接口。為取得此效果,需要在新類(lèi)中嵌入一個(gè)現(xiàn)有類(lèi)的private對(duì)象。但有時(shí),允許類(lèi)的用戶(hù)直接訪(fǎng)問(wèn)新類(lèi)中的組合成分是極具意義的,即將成員對(duì)象聲明為public。如果成員對(duì)象自身都隱藏了具體實(shí)現(xiàn),那么這種做法是安全的。當(dāng)用戶(hù)能夠了解到你正在組裝一組部件時(shí),會(huì)使得端口更加易于理解。比如car對(duì)象可由public的engine對(duì)象、wheel對(duì)象、window對(duì)象和door對(duì)象組合。但務(wù)必要記得這僅僅是一個(gè)特例,一般情況下應(yīng)該使域成為private。在繼承的時(shí)候,使用某個(gè)現(xiàn)有類(lèi),并開(kāi)發(fā)一個(gè)它的特殊版本。通常,這意味著你在使用一個(gè)通用類(lèi),并為了某種特殊需要而將其特殊化。稍微思考一下就會(huì)發(fā)現(xiàn),用一個(gè)“交通工具”對(duì)象來(lái)構(gòu)成一部“車(chē)子”是毫無(wú)意義的,因?yàn)椤败?chē)子”并不包含“交通工具”,它僅是一種交通工具(is-a關(guān)系)。
“is-a”(是一個(gè))的關(guān)系是用繼承來(lái)表達(dá)的,而“has-a”(有一個(gè))的關(guān)系則是用組合來(lái)表達(dá)的。
到底是該用組合還是繼承,一個(gè)最清晰的判斷方法就是問(wèn)一問(wèn)自己是否需要從新類(lèi)向基類(lèi)進(jìn)行向上轉(zhuǎn)型,需要的話(huà)就用繼承,不需要的話(huà)就用組合方式。
關(guān)鍵字
對(duì)final關(guān)鍵字的誤解
當(dāng)final修飾的是基本數(shù)據(jù)類(lèi)型時(shí),它指的是數(shù)值恒定不變(就是編譯期常量,如果是static final修飾,則強(qiáng)調(diào)只有一份),而對(duì)對(duì)象引用而不是基本類(lèi)型運(yùn)用final時(shí),其含義會(huì)有一點(diǎn)令人迷惑,因?yàn)橛糜趯?duì)象引用時(shí),final使引用恒定不變,一旦引用被初始化指向一個(gè)對(duì)象,就無(wú)法再把它指向另一個(gè)對(duì)象。然而,對(duì)象其自身卻是可以被修改的,java并未提供使任何對(duì)象恒定不變的途徑(但可以自己編寫(xiě)類(lèi)以取得使對(duì)象恒定不變的效果),這一限制同樣適用數(shù)組,它也是對(duì)象。? 使用final方法真的可以提高程序效率嗎?
將一個(gè)方法設(shè)成final后,編譯器就可以把對(duì)那個(gè)方法的所有調(diào)用都置入“嵌入”調(diào)用里。只要編譯器發(fā)現(xiàn)一個(gè)final方法調(diào)用,就會(huì)(根據(jù)它自己的判斷)忽略為執(zhí)行方法調(diào)用機(jī)制而采取的常規(guī)代碼插入方法(將自變量壓入堆棧;跳至方法代碼并執(zhí)行它;跳回來(lái);清除堆棧自變量;最后對(duì)返回值進(jìn)行處理)。相反,它會(huì)用方法主體內(nèi)實(shí)際代碼的一個(gè)副本來(lái)替換方法調(diào)用。這樣做可避免方法調(diào)用時(shí)的系統(tǒng)開(kāi)銷(xiāo)。當(dāng)然,若方法體積太大,那么程序也會(huì)變得雍腫,可能受到到不到嵌入代碼所帶來(lái)的任何性能提升。因?yàn)槿魏翁嵘急换ㄔ诜椒▋?nèi)部的時(shí)間抵消了。
在最近的java版本中,虛擬機(jī)(特別是hotspot技術(shù))能自動(dòng)偵測(cè)這些情況,并頗為“明智”地決定是否嵌入一個(gè)final 方法。然而,最好還是不要完全相信編譯器能正確地作出所有判斷。通常,只有在方法的代碼量非常少,或者想明確禁止方法被覆蓋的時(shí)候,才應(yīng)考慮將一個(gè)方法設(shè)為final。?
類(lèi)內(nèi)所有private 方法都自動(dòng)成為final。由于我們不能訪(fǎng)問(wèn)一個(gè)private 方法,所以它絕對(duì)不會(huì)被其他方法覆蓋(若強(qiáng)行這樣做,編譯器會(huì)給出錯(cuò)誤提示)?蔀橐粋(gè)private方法添加final指示符,但卻不能為那個(gè)方法提供任何額外的含義。
9.策略設(shè)計(jì)模式與適配器模式的區(qū)別
? 策略設(shè)計(jì)模式
創(chuàng)建一個(gè)能夠根據(jù)所傳遞的參數(shù)對(duì)象的不同而具有不同行為的方法,被稱(chēng)為策略設(shè)? 計(jì)模式,這類(lèi)方法包含所要執(zhí)行的算法中固定不變的部分,而“策略”包含變化的部分。策略就是傳遞進(jìn)去的參數(shù)對(duì)象,它包含要執(zhí)行的代碼。適配器模式
在你無(wú)法修改你想要使用的類(lèi)時(shí),可以使用適配器模式,適配器中的代碼將接受你所擁有的接口,并產(chǎn)生你所需要的接口。
內(nèi)部類(lèi)與組合是完全不同的概念,這一點(diǎn)很重要。
? 為什么需要內(nèi)部類(lèi)? — 主要是解決了多繼承的問(wèn)題,繼承具體或抽象類(lèi) ? ? 10.內(nèi)部類(lèi)
?
一般來(lái)說(shuō),內(nèi)部類(lèi)繼承自某個(gè)類(lèi)或?qū)崿F(xiàn)某個(gè)接口,內(nèi)部類(lèi)的代碼操作創(chuàng)建它的外圍類(lèi)的對(duì)象。所以可以認(rèn)為內(nèi)部類(lèi)提供了某種進(jìn)入其外圍類(lèi)的窗口。內(nèi)部類(lèi)最吸引人的原因是:每個(gè)內(nèi)部類(lèi)都能獨(dú)立地繼承自一個(gè)(接口的)實(shí)現(xiàn),所以無(wú)論外圍類(lèi)是否已經(jīng)繼承了某個(gè)(接口的)實(shí)現(xiàn),對(duì)于內(nèi)部類(lèi)都沒(méi)有影響。
如果沒(méi)有內(nèi)部類(lèi)提供的、可以繼承多個(gè)具體的或抽象的類(lèi)的能力,一些設(shè)計(jì)與編程問(wèn)題就很難解決。從這個(gè)角度看,內(nèi)部類(lèi)使得多重繼承的解決方案變得完整。接口解決了部分問(wèn)題,而內(nèi)部類(lèi)有效的實(shí)現(xiàn)了“多重繼承”。也就是說(shuō),內(nèi)部類(lèi)允許繼承多個(gè)非接口類(lèi)型。?
考慮這樣一種情形:如果必須在一個(gè)類(lèi)中以某種方式實(shí)現(xiàn)兩個(gè)接口。由于接口的靈活性,你有兩種選擇:使用單一類(lèi)或者使用內(nèi)部類(lèi)。但如果擁有的是抽象的類(lèi)或具體的類(lèi),而不是接口,那就只能使用內(nèi)部類(lèi)才能實(shí)現(xiàn)多重繼承。
使用內(nèi)部類(lèi),還可以獲得其他一些特性:創(chuàng)建內(nèi)部類(lèi)對(duì)象的時(shí)刻并不依賴(lài)于外圍類(lèi)對(duì)象的創(chuàng)建。
-內(nèi)部類(lèi)并沒(méi)有令人迷惑的is-a關(guān)系,它就是一個(gè)獨(dú)立的實(shí)體。
類(lèi)型 — 不可變
? ? 用于string的“+”與“+=”是java中僅有的兩個(gè)重載過(guò)的操作符,而java并不允許程序員重載任何操作符。
考慮到效率因素,編譯器會(huì)對(duì)string的多次+操作進(jìn)行優(yōu)化,優(yōu)化使用stringbuilder操作(javap-c class字節(jié)碼文件名 命令查看具體優(yōu)化過(guò)程)。這讓你覺(jué)得可以隨意使用string對(duì)象,反正編譯器會(huì)為你自動(dòng)地優(yōu)化性能。但編譯器能優(yōu)化到什么程度還不好說(shuō),不一定能優(yōu)化到使用stringbuilder代替string相同的效果。比如:
? ? ? ? ? ? ? public class witherstringbuilder {
public string implicit(string[] fields){ string result = ”“;
for(int i = 0;i < ;i++)result += fields[i];
return result;
} ? ? ? ? ? ? ? ?
public string explicit(string[] fields){
stringbuilder result = new stringbuilder();
for(int i = 0;i < ;i++)(fields[i]);
return ng();
} }
運(yùn)行javap-c witherstringbuilder,可以看到兩個(gè)方法對(duì)應(yīng)的字節(jié)碼。implicit方法:
public implicit([]);code: 0: ldc #16 // string 2: astore_2 3: iconst_0 4: istore_3 5: goto 32 8: new #18 // class java/lang/stringbuilder 11: dup 12: aload_2 13: invokestatic #20 // method java/lang/f:(ljava/lang/object;)ljava/lang/string;16: invokespecial #26 // method java/lang/stringbuilder.”< init>”:(ljava/lang/string;)v 19: aload_1 20: iload_3 21: aaload 22: invokevirtual #29 // method java/lang/ pend:(ljava/lang/string;)ljava/lang/stringbuilder;25: invokevirtual #33 // method java/lang/ string:()ljava/lang/string;28: astore_2 29: iinc 3, 1 32: iload_3 33: aload_1 34: arraylength 35: if_icmplt 8 38: aload_2 39: areturn public implicit([]);code: 0: ldc #16 // string 2: astore_2 3: iconst_0 4: istore_3 5: goto 32 8: new #18 // class java/lang/stringbuilder 11: dup 12: aload_2 13: invokestatic #20 // method java/lang/f:(ljava/lang/object;)ljava/lang/string;16: invokespecial #26 // method java/lang/stringbuilder.”< init>”:(ljava/lang/string;)v 19: aload_1 20: iload_3 21: aaload 22: invokevirtual #29 // method java/lang/ pend:(ljava/lang/string;)ljava/lang/stringbuilder;25: invokevirtual #33 // method java/lang/ string:()ljava/lang/string;28: astore_2 29: iinc 3, 1 32: iload_3 33: aload_1 34: arraylength 35: if_icmplt 8 38: aload_2 39: areturn 可以發(fā)現(xiàn),stringbuilder是在循環(huán)之內(nèi)構(gòu)造的,這意味著每經(jīng)過(guò)循環(huán)一次,就會(huì)創(chuàng)建一個(gè)新的stringbuilder對(duì)象。
explicit方法:
public explicit([]);code: 0: new #18 // class java/lang/stringbuilder 3: dup 4: invokespecial #45 // method java/lang/stringbuilder.”< init>”:()v 7: astore_2 8: iconst_0 9: istore_3 10: goto 24 13: aload_2 14: aload_1 15: iload_3 16: aaload 17: invokevirtual #29 // method java/lang/ pend:(ljava/lang/string;)ljava/lang/stringbuilder;20: pop 21: iinc 3, 1 24: iload_3 25: aload_1 26: arraylength 27: if_icmplt 13 30: aload_2 31: invokevirtual #33 // method java/lang/ string:()ljava/lang/string;34: areturn } 可以看到,不僅循環(huán)部分的代碼更簡(jiǎn)短、更簡(jiǎn)單,而且它只生成了一個(gè)stringbuilder對(duì)象。顯式的創(chuàng)建stringbuilder還允許你預(yù)先為其指定大小。如果你已經(jīng)知道最終的字符串大概有多長(zhǎng),那預(yù)先指定stringbuilder的大小可以避免多次重新分配緩沖。
####總結(jié)
因此,當(dāng)你為一個(gè)類(lèi)重寫(xiě)tostring()方法時(shí),如果字符串操作比較簡(jiǎn)單,那就可以信賴(lài)編譯器,它會(huì)為你合理地構(gòu)造最終的字符串結(jié)果。但是,如果你要在tostring()方法中使用循環(huán),那么最好自己創(chuàng)建一個(gè)stringbuilder對(duì)象,用它來(lái)構(gòu)造最終的結(jié)果。
? .printf()()方法模仿自c的printf,可以格式化字符串,兩者是完全等價(jià)的。
java中,ter類(lèi)處理。
()方法參考了c中的sprintf()方法,以生成格式化的string對(duì)象,是一個(gè)static方法,()方法一樣的參數(shù),但返回一個(gè)string對(duì)象。當(dāng)你只需使用format()方法一次的時(shí)候,該方法很方便。
import ;import ter;
public class simpleformat {
public static void main(string[] args){
int x = 5;
double y = 5.324667;
.printf(”row 1: [%d %f]n“, x, y);.format(”row 1: [%d %f]n“, x, y);
formatter f = new formatter();(”row 1: [%d %f]n“, x, y);
string str = (”row 1: [%d %f]n", x, y);.println(str);integer[][] a = {
{1, 2, 3}, {4, 5, 6},{7, 8, 3}, {9, 10, 6}
};
.println(string(a));
} }
12.序列化控制
? 當(dāng)我們對(duì)序列化進(jìn)行控制時(shí),可能某個(gè)特定子對(duì)象不想讓java序列化機(jī)制自動(dòng)保存與恢復(fù)。如果子對(duì)象表示的是我們不希望將其序列化的敏感信息(如密碼),通常會(huì)面臨這種情況。即使對(duì)象中的這些信息是private屬性,一經(jīng)序列化處理,人們就可以通過(guò)讀取文件或者攔截網(wǎng)絡(luò)傳輸?shù)姆绞絹?lái)訪(fǎng)問(wèn)到它。有兩種辦法可以防止對(duì)象的敏感部分被序列化:
? 實(shí)現(xiàn)externalizable代替實(shí)現(xiàn)serializable接口來(lái)對(duì)序列化過(guò)程進(jìn)行控制,externalizable繼承了serializable接口,同時(shí)增添了兩個(gè)方法:writeexternal()和readexternal()。
兩者在反序列化時(shí)的區(qū)別:
-對(duì)serializable對(duì)象反序列化時(shí),由于serializable對(duì)象完全以它存儲(chǔ)的二進(jìn)制位為基礎(chǔ)來(lái)構(gòu)造,因此并不會(huì)調(diào)用任何構(gòu)造函數(shù),因此serializable類(lèi)無(wú)需默認(rèn)構(gòu)造函數(shù),但是當(dāng)serializable類(lèi)的父類(lèi)沒(méi)有實(shí)現(xiàn)serializable接口時(shí),反序列化過(guò)程會(huì)調(diào)用父類(lèi)的默認(rèn)構(gòu)造函數(shù),因此該父類(lèi)必需有默認(rèn)構(gòu)造函數(shù),否則會(huì)拋異常。-對(duì)externalizable對(duì)象反序列化時(shí),會(huì)先調(diào)用類(lèi)的不帶參數(shù)的構(gòu)造方法,這是有別于默認(rèn)反序列方式的。如果把類(lèi)的不帶參數(shù)的構(gòu)造方法刪除,或者把該構(gòu)造方法的訪(fǎng)問(wèn)權(quán)限設(shè)置為private、默認(rèn)或protected級(jí)別,dexception: no valid constructor異常,因此externalizable對(duì)象必須有默認(rèn)構(gòu)造函數(shù),而且必需是public的。
-externalizable的替代方法:如果不是特別堅(jiān)持實(shí)現(xiàn)externalizable接口,那么還有另一種方法。我們可以實(shí)現(xiàn)serializable接口,并添加writeobject()和readobject()的方法。一旦對(duì)象被序列化或者重新裝配,就會(huì)分別調(diào)用那兩個(gè)方法。也就是說(shuō),只要提供了這兩個(gè)方法,就會(huì)優(yōu)先使用它們,而不考慮默認(rèn)的序列化機(jī)制。
這些方法必須含有下列準(zhǔn)確的簽名:
private void writeobject(objectoutputstream stream)throws ioexception;
private void readobject(objectinputstream stream)
throws ioexception, classnotfoundexception
-可以用transient關(guān)鍵字逐個(gè)字段地關(guān)閉序列化,它的意思是“不用麻煩你保存或恢復(fù)數(shù)據(jù)—我自己會(huì)處理的”。由于externalizable對(duì)象在默認(rèn)情況下不保存它們的任何字段,所以transient關(guān)鍵字只能和serializable對(duì)象一起使用。
java編程思想內(nèi)容篇三
這是一份試圖提綱挈領(lǐng)的讀書(shū)筆記,《java編程思想》這本八百多頁(yè)的書(shū)娓娓道來(lái)地包含了太多細(xì)節(jié),這對(duì)讀者是非常貼心的,我也強(qiáng)烈建議細(xì)細(xì)讀這本書(shū),如果你希望在短時(shí)間內(nèi)學(xué)會(huì)java這種語(yǔ)言,那么這本書(shū)不是最好的選擇,你可以看看譚浩強(qiáng)系列。我把看這本書(shū)的過(guò)程中,個(gè)人覺(jué)得每一章中最重要的思想、用整理在這里,希望自己回顧的時(shí)候有所參照和提高。也希望大家?guī)е瑯拥哪康膩?lái)看本篇讀書(shū)筆記。
第一章 對(duì)象導(dǎo)論
比起過(guò)程型語(yǔ)言編寫(xiě)的程序,用面向?qū)ο笳Z(yǔ)言編寫(xiě)的程序更加簡(jiǎn)單、易于理解、可復(fù)用!禼++編程思想》里也有這一章,是一個(gè)拋磚引自己的玉的章節(jié),不明白可以跳過(guò),回頭再看。
第二章 一切都是對(duì)象
java語(yǔ)言里面,一切都是對(duì)象,并且程序員是通過(guò)引用來(lái)操縱對(duì)象。一個(gè)簡(jiǎn)單的例子,非常輕松地讓讀者進(jìn)入java的世界。需要注意的是java數(shù)據(jù)會(huì)儲(chǔ)存在5個(gè)不同的地方:寄存器、堆棧、堆、常量存儲(chǔ)、非ram存儲(chǔ),用new創(chuàng)建的一般對(duì)象都放在堆中,而特殊的基本對(duì)象放在堆棧中,如果想把基本對(duì)象也放在堆中,需要包裝基本類(lèi)型。
第三章 操作符
java中的操作符語(yǔ)法類(lèi)似于c,所以學(xué)習(xí)起來(lái)一點(diǎn)困難也沒(méi)有。要特別注意兩個(gè)比較大的整數(shù)相加或者相乘的時(shí)候的溢出問(wèn)題,用long或者biginteger解決這個(gè)問(wèn)題。
第四章 控制執(zhí)行流程
我想起《pointer on c》這本書(shū)第一章就有這一句話(huà),本書(shū)適合那些希望迅速學(xué)習(xí)一門(mén)新語(yǔ)言而不是被“為什么if和for很重要”的弱智問(wèn)題耽擱進(jìn)度的讀者。呵呵,這一章很不厭其煩地介紹了運(yùn)算、操作符優(yōu)先級(jí)、類(lèi)型轉(zhuǎn)換、選擇循環(huán)等基本特性,有c或者c++編程經(jīng)驗(yàn)的讀者可以大概瀏覽一下。
第五章 初始化和清理
關(guān)于初始化:
1.初始化很重要,一定不要忘記。而且java編譯器會(huì)很好的防止使用未初始化數(shù)據(jù)的意外,這是比c和c++更優(yōu)的地方。
2.編譯器初始化的順序?yàn)椋?/p>
a.類(lèi)首次加載的時(shí)候,有關(guān)靜態(tài)初始化的所有動(dòng)作都會(huì)執(zhí)行。
a1.類(lèi)的加載包括首次創(chuàng)建該類(lèi)型的對(duì)象,或者該類(lèi)的靜態(tài)方法/靜態(tài)域首次被訪(fǎng)問(wèn)
a2.靜態(tài)域的初始化在一切初始化之前,即靜態(tài)變量散布在代碼不同的地方,它們也會(huì)在任何方法(包括構(gòu)造器)調(diào)用之前被初始化
b.當(dāng)用new calssname()創(chuàng)建對(duì)象的時(shí)候,會(huì)在堆上開(kāi)辟足夠的存儲(chǔ)空間,這塊存儲(chǔ)空間被清零,然后執(zhí)行字段的初始化動(dòng)作。(這里的字段初始化都是非靜態(tài)的,因?yàn)殪o態(tài)的變量已經(jīng)在a中執(zhí)行完畢,而且靜態(tài)變量存儲(chǔ)在不同的地方,靜態(tài)數(shù)據(jù)只占用一份存儲(chǔ)空間)
c.執(zhí)行構(gòu)造器
關(guān)于清理
c++關(guān)于清理的部分包含很大不確定性。目前需要知道的事情是,正常情況下,我們是不需要調(diào)用finalize方法的,而且垃圾回收區(qū)會(huì)自動(dòng)回收不再使用的對(duì)象,同時(shí)我們需要自己注意一些需要關(guān)閉的文件。
需要注意的是,用=對(duì)數(shù)組進(jìn)行“賦值”的時(shí)候,實(shí)際上是引用的傳遞,就是說(shuō),二者指向同一堆。
第六章 訪(fǎng)問(wèn)權(quán)限控制
關(guān)于包
你應(yīng)該有一個(gè)自己的域名,這樣發(fā)布你的java程序的時(shí)候,就可以將你的包名設(shè)置為你的域名倒轉(zhuǎn)。想要正確讓包工作,要正確設(shè)置classpath,對(duì)于新手來(lái)說(shuō),這的確是一個(gè)挑戰(zhàn)。我當(dāng)初就難到了。
關(guān)于訪(fǎng)問(wèn)權(quán)限修飾詞
值得注意的是,如果兩個(gè)編譯單元放在同一個(gè)目錄下并且都沒(méi)有設(shè)置包名的話(huà),他們對(duì)于對(duì)方都是擁有包訪(fǎng)問(wèn)權(quán)限的。訪(fǎng)問(wèn)權(quán)限修飾詞是修飾方法和數(shù)據(jù),而不是類(lèi)。類(lèi)只有兩種訪(fǎng)問(wèn)權(quán)限,包訪(fǎng)問(wèn)權(quán)限或public訪(fǎng)問(wèn)權(quán)限。默認(rèn)為包訪(fǎng)問(wèn)權(quán)限。如果不希望其它任何人對(duì)該類(lèi)擁有訪(fǎng)問(wèn)權(quán)限,可以把所有的構(gòu)造器設(shè)置為private。但是有一個(gè)例外,可以通過(guò)該類(lèi)自己的static成員內(nèi)部創(chuàng)建(于是就有了工廠設(shè)計(jì)模式和單例設(shè)計(jì)模式)。
第七章 復(fù)用類(lèi)
有三種方法復(fù)用類(lèi):組合,繼承,代理。
組合即是在新的類(lèi)里面放上已經(jīng)定義的類(lèi)的對(duì)象,然后通過(guò)調(diào)用它的方法來(lái)實(shí)現(xiàn)自己的功能。
繼承是通過(guò)extends關(guān)鍵詞繼承某一父類(lèi),這樣就能訪(fǎng)問(wèn)父類(lèi)的所有public方法(因此為了繼承,一般的規(guī)則是將父類(lèi)的所有數(shù)據(jù)成員都指定為private,將所有的方法都指定為public)。子類(lèi)的初始化需要注意的是,(當(dāng)創(chuàng)建了一個(gè)子類(lèi)的對(duì)象時(shí),該對(duì)象包含一個(gè)基類(lèi)的子對(duì)象)java會(huì)在子類(lèi)的構(gòu)造器中插入對(duì)基類(lèi)默認(rèn)構(gòu)造器的調(diào)用。但是如果沒(méi)有默認(rèn)的基類(lèi)構(gòu)造器,或者想調(diào)用一個(gè)帶參數(shù)的基類(lèi)構(gòu)造器,就必須用關(guān)鍵詞super顯式地編寫(xiě)調(diào)用基類(lèi)構(gòu)造器的語(yǔ)句,并且配上適當(dāng)?shù)膮?shù)列表。
代理很有意思,(我們姑且使用導(dǎo)出類(lèi)和基類(lèi)這樣的字眼,但要清楚我們不是在討論繼承里面的關(guān)鍵詞)在導(dǎo)出類(lèi)里保存一個(gè)基類(lèi)的對(duì)象,然后用自己的方法對(duì)該基類(lèi)的種種方法進(jìn)行包裝。
如何決定使用哪種方法復(fù)用類(lèi)呢?is-a就繼承,has-a就用組合。而且,組合比繼承總體上使用更廣泛、代價(jià)更小。
向上轉(zhuǎn)型
這個(gè)就牛逼了,第八章,第九章,第十章都與此密切相關(guān)?赐瓯緯(shū)之后印象最深的就是向上轉(zhuǎn)型了。
使用final的原因有很多種,一定要弄清楚為什么使用final,是由于設(shè)計(jì)還是效率。
final作用于數(shù)據(jù)的時(shí)候:final作用在基本對(duì)象比如int上,該值就成為不可改變的,一旦被初始化就無(wú)法再被更改,但是作用在普通的對(duì)象引用的時(shí)候,final使引用恒定不變,但是引用指向的對(duì)象是可變的。編譯器需要我們確保final對(duì)象一定要被初始化,我們可以通過(guò)在構(gòu)造器中初始化他們,以達(dá)到相對(duì)自由的效果(稱(chēng)為空白final,我認(rèn)為這個(gè)名字容易讓人誤解)。java允許在參數(shù)列表中以聲明的方式將參數(shù)指明為final,這一特性主要用來(lái)向匿名內(nèi)部類(lèi)傳遞數(shù)據(jù)(這很重要)。
final作用于方法的時(shí)候,說(shuō)明作者想保持該方法在繼承的過(guò)程中不被改變,并且不被覆蓋。同時(shí),被final修飾的方法會(huì)被關(guān)閉“動(dòng)態(tài)綁定”,這樣編譯器就會(huì)為final方法調(diào)用生成“有限”有效的代碼。之所以說(shuō)有限,是因?yàn)殡S著編譯器的牛逼,它生成的代碼越來(lái)越有效。
final作用于類(lèi)的時(shí)候,即是作者聲明對(duì)該類(lèi)的設(shè)計(jì)不允許任何繼承。
學(xué)習(xí)得更深入一些,可能對(duì)以下事實(shí)感到有興趣:java中所有的事物都是對(duì)象,每個(gè)類(lèi)的編譯代碼都存在于電腦中的文件夾里(文件夾的層次根據(jù)反轉(zhuǎn)域名得到),該文件只有在需要使用程序代碼時(shí)才被加載。具體的說(shuō),就是“類(lèi)在其任何static成員函數(shù)(包括構(gòu)造函數(shù))被訪(fǎng)問(wèn)時(shí)加載”。第八章 多態(tài)
多態(tài)的重要基本原理就是向上轉(zhuǎn)型:繼承允許將對(duì)象視為它自己本身的類(lèi)型或其基類(lèi)型加以處處理。
將一個(gè)方法調(diào)用和一個(gè)方法主題關(guān)聯(lián)起來(lái)稱(chēng)為綁定,java中所有的方法都是后期綁定(除了static方法和final方法),所以我們可以編寫(xiě)只與基類(lèi)打交道的程序代碼,并且這些代碼對(duì)所有的導(dǎo)出類(lèi)都可以正確運(yùn)行。
(為什么static不動(dòng)態(tài)綁定:因?yàn)閟tatic方法的主要用法就是用類(lèi)名.方法名這樣的方式來(lái)調(diào)用,不存在“發(fā)送消息給某個(gè)對(duì)象,讓對(duì)象判斷自己怎么做”這樣的情況。
為什么final不動(dòng)態(tài)綁定:這是早期final的一種用法,由程序員指定某方法為final,意味著程序員明了動(dòng)態(tài)綁定的機(jī)制,并且聲明該方法不需要?jiǎng)討B(tài)綁定,這樣可以獲得更好的性能。這種用法已經(jīng)很少使用了。)
初始化的時(shí)候,導(dǎo)出類(lèi)的構(gòu)造函數(shù)會(huì)自動(dòng)調(diào)用基類(lèi)的默認(rèn)構(gòu)造函數(shù),此過(guò)程一直遞歸到最基本的基類(lèi)。如果需要調(diào)用有參數(shù)的構(gòu)造函數(shù)就需要手動(dòng)執(zhí)行。反過(guò)來(lái),如果需要進(jìn)行清理工作(大部分時(shí)候我們都不需要),務(wù)必手動(dòng)執(zhí)行基類(lèi)的清理工作先。比如繼承鏈的每個(gè)類(lèi)都實(shí)現(xiàn)dispose()方法,那么執(zhí)行某個(gè)類(lèi)的清理工作的時(shí)候,e()。不過(guò)此種情況下,e()之前釋放成員對(duì)象,清理順序與執(zhí)行順序是相反的。
此外,構(gòu)造器方面有更加復(fù)雜的調(diào)用機(jī)制,我們不用理它,只需要知道一條有效的準(zhǔn)則“用盡可能簡(jiǎn)單的方法使對(duì)象進(jìn)入正常狀態(tài),如果可以的話(huà)避免調(diào)用其它方法”。
java編譯器能夠允許向上多態(tài),就是因?yàn)閖ava的機(jī)制能保存對(duì)象的類(lèi)型信息,即rtti,正因?yàn)檫@種機(jī)制,java編譯器也允許向下轉(zhuǎn)型,以獲得擴(kuò)展類(lèi)的“擴(kuò)展出”的方法。(另,擴(kuò)展類(lèi)“擴(kuò)展”了方法的這種繼承不是“純繼承”,這樣做好不好?用戶(hù)自己度量)。向下轉(zhuǎn)型失敗的話(huà)會(huì)拋出一個(gè)classcastexception。
雖然這一章都是在講多態(tài),但是多態(tài)并不總是解決問(wèn)題最好的方案,它有可能使事情不必要地復(fù)雜起來(lái),我們應(yīng)該總是優(yōu)先考慮更加靈活的組合。
第九章 接口
一種專(zhuān)門(mén)提供“接口”的類(lèi)叫抽象類(lèi),若含有至少一個(gè)abstract方法,該類(lèi)就必須被聲明為abstract的。抽象方法沒(méi)有方法體,派生類(lèi)必須實(shí)現(xiàn)它,否則派生類(lèi)也必須被生命為抽象的。
interface關(guān)鍵詞使抽象的概念更進(jìn)了一步:1.這個(gè)“類(lèi)”完全抽象。2.一個(gè)類(lèi)可以向上轉(zhuǎn)型為多種interface。要讓一個(gè)類(lèi)遵循某個(gè)特定接口,需要使用implement關(guān)鍵字。
在這一章中出現(xiàn)了“策略設(shè)計(jì)模式”這個(gè)詞。創(chuàng)建一個(gè)能夠根據(jù)所傳遞的參數(shù)對(duì)象的不同而具有不同行為的方法,被稱(chēng)為策略設(shè)計(jì)模式。
策略設(shè)計(jì)模式跟適配器設(shè)計(jì)模式聯(lián)合使用可以提供非常強(qiáng)大的功能,比如我們遇到了無(wú)法更改的類(lèi)(別人編寫(xiě)的),想要它滿(mǎn)足我們的接口然后放到設(shè)計(jì)模式里面去(當(dāng)然滿(mǎn)足了接口之后的用法就不止如此了),就可以編寫(xiě)一個(gè)適配器,包裝該類(lèi)同時(shí)產(chǎn)生我所需要的接口。
使用抽象類(lèi)和接口的兩個(gè)原因是:1.在多重繼承關(guān)系中(這真的很常見(jiàn),看看java api就知道了),導(dǎo)出類(lèi)可以被向上轉(zhuǎn)型為每一個(gè)接口。2.防止客戶(hù)端程序員創(chuàng)建該類(lèi)的對(duì)象。那么我們?cè)撌褂贸橄箢?lèi)還是接口呢?事實(shí)上,如果知道某事物應(yīng)該成為一個(gè)基類(lèi),那么第一選擇應(yīng)該是使它成為一個(gè)接口。
接口之間的繼承能夠形成很好的體系,更像我們的現(xiàn)實(shí)生活。但是要特別注意的是,在不同接口中使用相同的方法名通常會(huì)造成代碼可讀性的混亂,令人不快。
工廠方法設(shè)計(jì)模式是又一個(gè)重要的設(shè)計(jì)模式。我們?cè)诖a中增加額外的間接性,一個(gè)重要的原因是想要?jiǎng)?chuàng)建框架。
java編程思想內(nèi)容篇四
in the following code, which is the earliest statement, where the object originally held in e, may be garbage collected:
class test {
static void main(string args []){
ee e = new employee(“bob”, 48);
atepay();
n(etails());
6.e = null;
7.e = new employee(“denise”, 36);
atepay();
n(etails());
10.}
11.}
only one:
in the following code, which is the earliest statement, where the object originally held in e, may be garbage collected:
class test {
static void main(string args []){
ee e = new employee(“bob”, 48);
atepay();
n(etails());
6.e = null;
7.e = new employee(“denise”, 36);
atepay();
n(etails());
10.}
11.}
only one:
10
11
7
8
2:exhibit :
class test(e static int j = 0;
e static boolean methodb(int k)(5.j += k;
true;
6.)
static void methoda(int i){
n b:
10.b = i < 10 | methodb(4);
11.b = i < 10 || methodb(8);
12.)
static void main(string args[] }(a(0);
n(j);
17.)
18.)
what is the result?
program prints “0”
program prints “4”
program prints “8”
program prints “12”
3:what is written to the standard output given the following statement:n(4|7);
select the right answer:
a.4
b.5
c.6
d.7
4:
select valid identifier of java:
select valid identifier of java:
a.%passwd
b.3d_game
c.$charge
5:設(shè)有變量說(shuō)明語(yǔ)句int a=1,b=0;
則執(zhí)行以下程序段的輸出結(jié)果為()。
switch(a)
{
case 1:
switch(b)
{
case 0:printf(“**0**”);break;
case 1:printf(“**1**”);break;
}
case 2:printf(“**2**”);break;
}
printf(“ ”);
a.**0**
b.**0****2**
c.**0****1****2**
d.有語(yǔ)法錯(cuò)誤
6:in the following pieces of code, which one will compile without any error?
buffer sb1 = “abcd”;
n b = new boolean(“abcd”);
c.c: byte b = 255;
fl = 1.2;
7:
what is the result when you compile and run the following code?
public class throwsdemo
{
static void throwmethod()
{
n(“inside throwmethod.”);
throw new illegalaccessexception(“demo”);
}
public static void main(string args[])
{
try
{
throwmethod();
}
catch(illegalaccessexception e)
{
n(“caught ” + e);
}
}
}
choices:
what is the result when you compile and run the following code?
public class throwsdemo
{
static void throwmethod()
{
n(“inside throwmethod.”);
throw new illegalaccessexception(“demo”);
}
public static void main(string args[])
{
try
{
throwmethod();
}
catch(illegalaccessexception e)
{
n(“caught ” + e);
}
}
}
choices:
ation error
e error
e successfully, nothing is ed by caught:laccessexcption: demo
8:which of the following statements are not legal?
l = 4990;
i = 4l;
d = 34.4;
t = 0.9f.9:
give the following java class:
public class example{
public static void main(string args[]){
static int x[] = new int[15];
n(x[5]);
}
}
which statement is corrected?
give the following java class:
public class example{
public static void main(string args[]){
static int x[] = new int[15];
n(x[5]);
}
}
which statement is corrected?
compile, some error will run, some error will is is null.10:下面關(guān)于變量及其范圍的陳述哪些是錯(cuò)的。
a.實(shí)例變量是類(lèi)的成員變量。
b.實(shí)例變量用關(guān)鍵字static聲明。
c.在方法中定義的局部變量在該方法被執(zhí)行時(shí)創(chuàng)建
d.局部變量在使用前必須被初始化。
11:
public class x{
public object m(){
object o = new float(3.14f);//line 3
object [] oa = new object[1];//line 4
oa[0] = o;//line 5
o=null;//line 6
return oa[0];//line 7
}
}
when is the float object, created in line 3,eligible for garbage collection?
public class x{
public object m(){
object o = new float(3.14f);//line 3
object [] oa = new object[1];//line 4
oa[0] = o;//line 5
o=null;//line 6
return oa[0];//line 7
}
}
when is the float object, created in line 3,eligible for garbage collection?
after line after line 6
after line 7(that is,as the method returns)
in this method
12:
which is the most appropriate code snippet that can be inserted at line 18 in the following code?
(assume that the code is compiled and run with assertions enabled)
.*;
class asserttest
4.{
e hashmap cctld;
asserttest()
8.{
= new hashmap();
(“in”, “india”);
(“uk”, “united kingdom”);
(“au”, “australia”);
13.// more code...14.}
15.// other methods.... string getcountry(string countrycode)
17.{
18.// what should be inserted here?
country =(string)(countrycode);
country;
21.}
22.}
which is the most appropriate code snippet that can be inserted at line 18 in the following code?
(assume that the code is compiled and run with assertions enabled)
.*;
class asserttest
4.{
e hashmap cctld;
asserttest()
8.{
= new hashmap();
(“in”, “india”);
(“uk”, “united kingdom”);
(“au”, “australia”);
13.// more code...14.}
15.// other methods.... string getcountry(string countrycode)
17.{
18.// what should be inserted here?
country =(string)(countrycode);
country;
21.}
22.}
countrycode!= null;
countrycode!= null : “country code can not be null”;
cctld!= null : “no country code data is available”;
cctld : “no country code data is available”;
13:
give the following code:
public class example{
public static void main(string args[]){
int l=0;
do{
n(“doing it for l is:”+l);
}while(—l>0)
n(“finish”);
}
}
which well be output:
give the following code:
public class example{
public static void main(string args[]){
int l=0;
do{
n(“doing it for l is:”+l);
}while(—l>0)
n(“finish”);
}
}
which well be output:
it for l is 3
it for l is 1
it for l is 2
it for l is 0
14:which statements about java code security are not true?
bytecode verifier loads all classes needed for the execution of a ing code is performed by the runtime runtime the bytecodes are loaded, checked and run in an interpreter. class loader adds security by separating the namespaces for the classes of the local file system from those imported from network sources.15:a class design requires that a member variable should be accessible only by same package, which modifer word should be used?
ted
modifer
e
16:character流與byte流的區(qū)別是
a.每次讀入的字節(jié)數(shù)不同
b.前者帶有緩沖,后者沒(méi)有
c.前者是塊讀寫(xiě),后者是字節(jié)讀寫(xiě)
d.二者沒(méi)有區(qū)別,可以互換使用
簡(jiǎn)答題
17:找出兩個(gè)字符串中最大子字符串,如“abractyeyt”,“dgdsaeactyey”的最大子串為“actyet”
18:假設(shè)你有一個(gè)用1001個(gè)整數(shù)組成的數(shù)組,這些整數(shù)是任意排列的,但是你知道所有的整數(shù)都在1到1000(包括1000)之間。此外,除一個(gè)數(shù)字出現(xiàn)兩次外,其他所有數(shù)字只出現(xiàn)一次。假設(shè)你只能對(duì)這個(gè)數(shù)組做一次處理,用一種算法找出重復(fù)的那個(gè)數(shù)字。如果你在運(yùn)算中使用了輔助的存儲(chǔ)方式,那么你能找到不用這種方式的算法嗎?
19:到底在哪里使用cascade=“...”?
20:使用tomcat部署應(yīng)用程序 emoryerror 嗎?如何解決的。
21:請(qǐng)寫(xiě)一個(gè)java程序?qū)崿F(xiàn)數(shù)據(jù)庫(kù)緩沖池的功能?
22:有200個(gè)正整數(shù),且每個(gè)數(shù)均在1000至9999之間。請(qǐng)編制函數(shù),其函數(shù)的功能是:要求按每個(gè)數(shù)的后三位的大小進(jìn)行升序排列,然后取出滿(mǎn)足此條件的前10個(gè)數(shù)依次存入數(shù)組bb中,如果后三位的數(shù)值相等,則按原先的數(shù)值進(jìn)行降序排列。
23:anonymous inner class(匿名內(nèi)部類(lèi))是否可以extends(繼承)其它類(lèi),是否可以implements(實(shí)現(xiàn))interface(接口)?
24:找出字符串a(chǎn)中包含的字符可以進(jìn)行的所有不同組合。例如:abccd中,ab,ac,bc,cc,abd等都是可能的組合。
25:下面的代碼在絕大部分時(shí)間內(nèi)都運(yùn)行得很正常,請(qǐng)問(wèn)在什么情況下會(huì)出現(xiàn)問(wèn)題?問(wèn)題的根源在哪里?
import .linkedlist;
public class stack {
linkedlist list = new linkedlist();
public synchronized void push(object x){
synchronized(list){
t(x);
notify();
}
}
public synchronized object pop()
throws exception {
synchronized(list){
if(()<= 0){
wait();
}
return last();
}
}
}
java編程思想內(nèi)容篇五
一 基礎(chǔ)知識(shí)點(diǎn)
1.面向?qū)ο蟪绦蛟O(shè)計(jì)(object-oriented programming oop),uml(unitied modelling language 統(tǒng)一建模語(yǔ)言)。將對(duì)象想像成“服務(wù)提供者”,它們看起來(lái)像什么?能夠提供哪 些服務(wù)?需要哪些對(duì)象? 中動(dòng)態(tài)綁定是默認(rèn)行為。java采用動(dòng)態(tài)內(nèi)存分配方式,通過(guò)new操作在堆(heap)的內(nèi) 存池中動(dòng)態(tài)創(chuàng)建對(duì)象。java存儲(chǔ)結(jié)構(gòu)類(lèi)型:1)寄存器2)堆棧,主要存儲(chǔ)對(duì)象引用3)堆,主要用于存放所有的java對(duì)象4)常量存儲(chǔ),也就是程序代碼區(qū)5)非ram存儲(chǔ),如流對(duì)象 和持久化對(duì)象;绢(lèi)型不用new來(lái)創(chuàng)建變量,而且這個(gè)變量直接存儲(chǔ)”值”,并置于堆棧中。eger和bigdecimal的使用。當(dāng)變量作為類(lèi)的成員使用時(shí) 當(dāng)變量作為類(lèi)的成員使用時(shí),java才確保給定其默認(rèn)初 當(dāng)變量作為類(lèi)的成員使用時(shí) 始值,但是在方法中定義的變量,它有可能是任意值。面向?qū)ο蟮某绦蛟O(shè)計(jì)可以歸納為“向 對(duì)象發(fā)送消息”。關(guān)鍵字static。c只能為public和protected成員進(jìn)行文檔注釋?zhuān)且部梢酝ㄟ^(guò)-private進(jìn)行標(biāo)記注 釋。javadoc常用方法: @see 引用其他類(lèi),link #member label},{@ {@docroot},{@inheritdoc},@version,@ author,@since,@param,@return,@throws,@deprecated。5.整數(shù)除法會(huì)直接去掉結(jié)果的小數(shù)位;绢(lèi)型的對(duì)象如果直接對(duì)它們賦值,對(duì)象指向同 一個(gè)常量存儲(chǔ)區(qū),但是如果通過(guò)對(duì)象來(lái)初始化則會(huì)指向不同的堆的存儲(chǔ)區(qū)。如:
string st1 = new string(“a”);string st2 = new string(“a”);st1==st2 false string st1 = “a”;string st2 = “a”;st1==st2 true
6.邏輯操作符:與(&&)、或(||)、非(!),其中與(&&)、或(||)會(huì)產(chǎn)生短路現(xiàn)象。& |也支持邏輯 也支持邏輯
運(yùn)算操作。運(yùn)算操作
7.直接常量中l(wèi)代表long,f代表float,d代表double。顯示二進(jìn)制形式的話(huà),可以通過(guò)integer 和long類(lèi)的靜態(tài)方法tobinarystring()。如:rystring(10l)。
8.在返回void的方法中沒(méi)有return語(yǔ)句,那么在該方法的結(jié)尾處會(huì)有一個(gè)隱式的return。
一 般情況下每個(gè)方法都會(huì)有一個(gè)顯示的return語(yǔ)句。用于強(qiáng)行退出循環(huán),不執(zhí)行循環(huán)中剩余的語(yǔ)句,而continue則停止執(zhí)行當(dāng)前的迭代,然后退回循環(huán)起始處,開(kāi)始下一次迭代。goto仍是java的一個(gè)保留字,但在語(yǔ)言中并未使用它。break和continue與標(biāo)簽一起使用,可以中斷循環(huán),直到標(biāo)簽所在的地方。this用法: public class leaf { int i = 0;leaf increment(){ i++;return this;} }
10.回答一個(gè)新技術(shù)的問(wèn)題大概思路和步驟是:我們想干什么,怎么干,干的過(guò)程中遇到了 什么問(wèn)題,現(xiàn)在用什么方式來(lái)解決。答題時(shí),先答是什么,再答有什么作用和要注意什么(這 部分最重要,展現(xiàn)自己的心得)。ze的使用:垃圾回收只與內(nèi)存有關(guān),當(dāng)“垃圾回收”時(shí),finalize()得到調(diào)用。java中 的對(duì)象都能被垃圾回收器回收,但是在“本地方法”的情況下,有可能在分配內(nèi)存時(shí)采用類(lèi) 似c語(yǔ)言的做法通過(guò)malloc()函數(shù)來(lái)分配存儲(chǔ)空間時(shí),這時(shí)只能通過(guò)free()函數(shù)來(lái)釋放空間,而這些釋放操作必須要放到finalize()方法中,垃圾回收器才能正確的釋放內(nèi)存!袄厥铡 都不保證一定會(huì)發(fā)生。
12.垃圾回收原理:引用記數(shù) 引用記數(shù)是一種簡(jiǎn)單但速度很慢的垃圾回收技術(shù)。每個(gè)對(duì)象都含有一個(gè) 引用記數(shù)
java 編程思想第四版 讀書(shū)筆記
引用記數(shù)器,當(dāng)有引用連接至對(duì)象時(shí),引用計(jì)數(shù)加1。當(dāng)引用離開(kāi)作用域或被置為null時(shí),引用計(jì)數(shù)減1。垃圾回收器會(huì)在含有全部對(duì)象的列表上遍歷,當(dāng)發(fā)現(xiàn)某個(gè)對(duì)象的引用計(jì)數(shù)為0 時(shí),就立即釋放其占用的空間。定位交互自引用的對(duì)象組所需的工作量極大,所以并沒(méi)有被 應(yīng)用于任何一種java虛擬機(jī)中。java虛擬機(jī)采用一種自適應(yīng) 自適應(yīng)的垃圾
回收技術(shù),java虛擬機(jī)會(huì) 自適應(yīng) 進(jìn)行監(jiān)視,如果所有對(duì)象都很穩(wěn)定,垃圾回收器的效率降低的話(huà),就切換到“標(biāo)記-清掃” 方式;同樣,java虛擬機(jī)會(huì)跟蹤“標(biāo)記-清掃”的效果,要是堆空間出現(xiàn)很多碎片,就會(huì)切 換回“停止-復(fù)制”方式!巴V-復(fù)制”,先暫停程序的運(yùn)行,然后將所有存活 存活的對(duì)象從當(dāng)前 存活 堆復(fù)制到另一個(gè)堆,沒(méi)有被復(fù)制的全部都是垃圾!皹(biāo)記-清掃”,從堆棧和靜態(tài)存儲(chǔ)區(qū)出發(fā),遍歷所有的引用,進(jìn)而找出所有存活的對(duì)象,每當(dāng)它找到一個(gè)存活對(duì)象,就會(huì)給對(duì)象設(shè)一個(gè) 標(biāo)記,這個(gè)過(guò)程中不會(huì)回收任何對(duì)象,只有全部標(biāo)記工作完成的時(shí)候,清理動(dòng)作才會(huì)開(kāi)始。在清理過(guò)程中,沒(méi)有標(biāo)記的對(duì)象將被釋放,不會(huì)發(fā)生下任何復(fù)制動(dòng)作。13.初始化順序:先靜態(tài)對(duì)象,后“非靜態(tài)”對(duì)象,先變量,再構(gòu)造函數(shù),然后是方法。靜態(tài) 初始化只有在必要時(shí)刻才會(huì)進(jìn)行,如果不引用其對(duì)象,那么該對(duì)象中的靜態(tài)成員將不會(huì)被創(chuàng) 建,而且它們只會(huì)在第一次被訪(fǎng)問(wèn)時(shí)進(jìn)行初始化,其后不會(huì)再次被初始化。14.對(duì)象的創(chuàng)建過(guò)程:1)當(dāng)首次創(chuàng)建對(duì)象時(shí),或類(lèi)的靜態(tài)方法/靜態(tài)域首次被訪(fǎng)問(wèn)時(shí),java 解釋器必須查找類(lèi)路徑,文件。2),有關(guān)靜態(tài)初始化的所有動(dòng)作都會(huì) 執(zhí)行。3)當(dāng)用new 創(chuàng)建對(duì)象時(shí),在堆上為對(duì)象分配存儲(chǔ)空間,而且這塊存儲(chǔ)空間會(huì)被清零,也就是說(shuō)它會(huì)自動(dòng)地將對(duì)象中的所有基本類(lèi)型數(shù)據(jù)都設(shè)置成默認(rèn)值,而引用是被設(shè)置成 null。4)執(zhí)行所有出現(xiàn)于字段定義處的初始化動(dòng)作。5)執(zhí)行構(gòu)造器。15.數(shù)組:常用方法的使用。binarysearch(),copyof(),aslist(),copyofrange(),equals(),fill(),sort(),tostring(),hashcode()。可變 參數(shù)列表:void f(float i,character? args)。枚舉類(lèi)型:enum,它可以在switch語(yǔ)句內(nèi)使用。16.類(lèi)的結(jié)構(gòu)依次為:1)包的注釋2)package的設(shè)置3)import導(dǎo)入設(shè)置4)類(lèi)的注釋5)類(lèi)的編 寫(xiě)。的訪(fǎng)問(wèn)權(quán)限:類(lèi)的訪(fǎng)問(wèn)權(quán)限只有public和默認(rèn)包訪(fǎng)問(wèn)權(quán)限,成員和方法有 public,protected,默認(rèn)包訪(fǎng)問(wèn)權(quán)限和private。使用類(lèi)的客戶(hù)端程序是無(wú)法訪(fǎng)問(wèn)包訪(fǎng)問(wèn)權(quán)限成員 的。包訪(fǎng)問(wèn)權(quán)限的類(lèi)的對(duì)象可以由包內(nèi)任何其他類(lèi)來(lái)創(chuàng)建和使用,但是包外則不行。18.為了繼承,一般的規(guī)則是將所有的數(shù)據(jù)成員都指定為private,將所有的方法指定為public 或protected。java會(huì)自動(dòng)在導(dǎo)出類(lèi)的構(gòu)造器中插入對(duì)基類(lèi)構(gòu)造器的調(diào)用。調(diào)用基類(lèi)的構(gòu)造器 必須是你在導(dǎo)出類(lèi)構(gòu)造器中要做的第一件事。19.代理,它是繼承與組合之間的中庸之道,因?yàn)槲覀儗⒁粋(gè)成員對(duì)象置于所要構(gòu)造的類(lèi)中(就像組合),但與此同時(shí)我們?cè)谛骂?lèi)中暴露了該成員對(duì)象的所有方法(就像繼承)。20.清理方法的順序:首先,執(zhí)行類(lèi)的所有特定的清理動(dòng)作,其順序同生成順序相反;然后,調(diào)用基類(lèi)的清理方法。除了內(nèi)存之外,不能依賴(lài)?yán)厥掌魅プ鋈魏问,如果需要進(jìn)行清理,最好是編寫(xiě)自己的清理方法,但不要使用finalize()。@override注解可以防止在你不想重載 時(shí)而意外地進(jìn)行了重載。21.組合與繼承之間的選擇:組合技術(shù)通常用于想在新類(lèi)中使用現(xiàn)有類(lèi)的功能而非它的接口,也就是在新類(lèi)的嵌入某個(gè)對(duì)象,讓其實(shí)現(xiàn)所需要的功能,但新類(lèi)的用戶(hù)看到的只是為新類(lèi)所 定義的接口,而非所嵌入對(duì)象的接口,一般情況下會(huì)在新類(lèi)中嵌入一個(gè)現(xiàn)有類(lèi)的private對(duì)象。而繼承,它是指使用某個(gè)現(xiàn)有類(lèi),并開(kāi)發(fā)一個(gè)它的特殊版本!癷s-a”(是一個(gè))的關(guān)系是用 繼承來(lái)表達(dá)的,而“has-a”(有一個(gè))的關(guān)系則是用組合來(lái)表達(dá)的。的用法:根據(jù)慣例,既是static又是final的域?qū)⒂么髮?xiě)表示,并使用下劃線(xiàn)分隔各個(gè)單 詞。類(lèi)中所有的private方法都隱式的指定為是final的。final類(lèi)中所有的方法都隱式指定為是 final的。當(dāng)前用hashmap替代了hashtable,用arraylist替代了vector。
java 編程思想第四版 讀書(shū)筆記
中除了static方法和final方法(private方法屬于final方法)之外,其他所有的方法都是 后期綁定。接口中的屬性都是public static final的,方法都是public 24.多態(tài):只有普通的方法調(diào)用可以是多態(tài)的。任何域訪(fǎng)問(wèn)操作都將由編譯器解析,因此不 是多態(tài)的。如果某個(gè)方法是靜態(tài)的,它的行為也不具有多態(tài)性。25.初始化的實(shí)際過(guò)程:1)在其他任
何事物發(fā)生之前,將分配給對(duì)象的存儲(chǔ)空間初始化成二 進(jìn)制的零。2)如前所述那樣調(diào)用基類(lèi)構(gòu)造器,此時(shí),調(diào)用被覆蓋后的方法(要在調(diào)用子類(lèi) 構(gòu)造器之前調(diào)用)。3)按照聲明的順序調(diào)用成員的初始化方法。4)調(diào)用導(dǎo)出類(lèi)的構(gòu)造器主 體。編寫(xiě)構(gòu)造器時(shí)有一條有效的準(zhǔn)則: “用盡可能簡(jiǎn)單的方法使對(duì)象進(jìn)入正常狀態(tài);如果可 以的話(huà),避免調(diào)用其他方法”。在構(gòu)造器內(nèi)唯一能夠安全調(diào)用的那些方法是基類(lèi)中的final方 法(也適用于private方法,它們自動(dòng)屬于final方法)。這些方法不能被覆蓋。26.一條通用的準(zhǔn)則是: “用繼承表達(dá)行為間的差異,并用字段表達(dá)狀態(tài)上的變化”。27.一個(gè)內(nèi)部類(lèi)的對(duì)象能訪(fǎng)問(wèn)其外圍對(duì)象的所有成員,還擁有其外圍類(lèi)的所有元素的訪(fǎng)問(wèn)權(quán)。在內(nèi)部類(lèi)中,如果你需要生成對(duì)外部類(lèi)對(duì)象的引用,可以使用外部類(lèi)的名字后面緊跟圓點(diǎn)和 this,(outerclass out = )。有時(shí)你可能想要告知某些其他對(duì)象,去創(chuàng)建其某個(gè) 內(nèi)部類(lèi)的對(duì)象,可以在new表達(dá)式中提供對(duì)其他外部類(lèi)對(duì)象的引用,語(yǔ)法(outerclass out = new outerclass, lass inner = innerclass())。在擁 有外部類(lèi)對(duì)象之前是不可能創(chuàng)建內(nèi)部類(lèi)對(duì)象的,但是,嵌套類(lèi)(靜態(tài)內(nèi)部類(lèi))除外。如果定 義一個(gè)匿名內(nèi)部類(lèi),并希望它使用一個(gè)在其外部定義的對(duì)象,那么其參數(shù)引用必須是final 的。匿名類(lèi)的實(shí)例初始化的實(shí)際效果就是構(gòu)造器,而且你不能重載實(shí)例初始化方法,它可以 擴(kuò)展類(lèi),也可以實(shí)現(xiàn)接口,但是實(shí)現(xiàn)接口,也只能實(shí)現(xiàn)一個(gè)接口。28.嵌套類(lèi)(靜態(tài)內(nèi)部類(lèi)):1)要?jiǎng)?chuàng)建嵌套類(lèi)的對(duì)象,并不需要其外圍類(lèi)的對(duì)象;2)不能從嵌 套類(lèi)的對(duì)象中訪(fǎng)問(wèn)非靜態(tài)的外圍類(lèi)對(duì)象。30.為什么需要內(nèi)部類(lèi):1)每個(gè)內(nèi)部類(lèi)都能獨(dú)立繼承自一個(gè)(接口的)實(shí)現(xiàn),所以無(wú)論外圍 類(lèi)是否已經(jīng)繼承了某個(gè)(接口的)實(shí)現(xiàn),對(duì)于內(nèi)部類(lèi)都沒(méi)有影響。2)內(nèi)部類(lèi)可以更好的實(shí) 現(xiàn)“多重繼承”。3)內(nèi)部類(lèi)可以有多個(gè)實(shí)例,每個(gè)實(shí)例都有自己的狀態(tài)信息,并且與其外圍 類(lèi)對(duì)象的信息相互獨(dú)立。4)在單個(gè)外圍類(lèi)中,可以讓多個(gè)內(nèi)部類(lèi)以不同的方式實(shí)現(xiàn)同一個(gè) 接口或繼承同一個(gè)類(lèi)。5)創(chuàng)建內(nèi)部類(lèi)對(duì)象的時(shí)刻并不依賴(lài)于外圍類(lèi)對(duì)象的創(chuàng)建。
6)內(nèi)部類(lèi) 并沒(méi)有令人迷惑的“is-a”關(guān)系,它是一個(gè)獨(dú)立的實(shí)體。31.閉包:它是一個(gè)可調(diào)用的對(duì)象,它記錄了一些信息,這些信息來(lái)自于創(chuàng)建它的作用域。通過(guò)內(nèi)部類(lèi)提供閉包的功能是優(yōu)良的解決方案。使用局部?jī)?nèi)部類(lèi)而不使用匿名內(nèi)部類(lèi)的的理 由是需要不止一個(gè)該內(nèi)部類(lèi)的對(duì)象,或者需要一個(gè)已命名的構(gòu)造器。32.內(nèi)部類(lèi)的繼承:內(nèi)部類(lèi)的構(gòu)造器必須連接到指向其外圍類(lèi)對(duì)象的引用,必須在構(gòu)造器內(nèi) 使用如下語(yǔ)法:();33.容器:list、set、query、map。程序中不應(yīng)該使用過(guò)時(shí)的vector,hashtable和stack。常用的類(lèi)有:collection,collections,arrays,arraylist,linkedlist,hashset,treeset,linkedhashset, hashmap,treemap,linkedhashmap,query,stack,priorityquery 迭代器:iteratror,listiterator3
java 編程思想第四版 讀書(shū)筆記
34.異常:把當(dāng)前異常對(duì)象重新拋出時(shí),printstacktrace()方法顯示原來(lái)異常拋出點(diǎn)的調(diào)用棧 信息,要想更新這個(gè)信息,可以調(diào)用fillinstacktrace()方法。如: throw(exception)stacktrace()。35.異常鏈:在捕獲一個(gè)異常后拋出另一個(gè)異常,而且希望把原始異常的信息保存下來(lái),F(xiàn) 在所有的throwable的子類(lèi)在構(gòu)造器中都可以接受一個(gè)cause(因由)對(duì)象作為參數(shù)。這個(gè)cause 就用來(lái)表示原始異常,這樣通過(guò)把原始異常傳遞給新的異常,使得即使在當(dāng)前位置創(chuàng)建并拋 出了新的異常,也能通過(guò)這個(gè)異常鏈追蹤到異常最初發(fā)生的位置。只有三種基本異常類(lèi)(error、exception、runtimeexception)提供了帶cause參數(shù)的構(gòu)造器,其他的異常只能使用 initcause()方法。36.當(dāng)覆蓋方法的時(shí)候,只能拋出在基類(lèi)方法的異常說(shuō)明里列出的那些異常,或者拋出的異 常的子類(lèi)或者不拋出異常。標(biāo)準(zhǔn)異常: throwable這個(gè)java類(lèi)被用來(lái)表示任何可以作為異常被拋出的類(lèi)。throwable 對(duì)象可分為兩種類(lèi)型(指從throwable繼承而得到的類(lèi)型):error用來(lái)表示編譯時(shí)和系統(tǒng)錯(cuò)誤(除
特殊情況外,一般不用你關(guān)心);exception是可以被拋出的基本類(lèi)型,在java類(lèi)庫(kù)、用 戶(hù)方法以及運(yùn)行時(shí)故障中都可能拋出exception型異常。所以java程序員關(guān)心的基類(lèi)型通常是 exception。eexception:java運(yùn)行時(shí)異常,它屬于java的標(biāo)準(zhǔn)運(yùn)行時(shí)檢測(cè)的一部分,它會(huì)自動(dòng)被 java虛擬機(jī)拋出,它也被稱(chēng)為“不受檢查異!,這種異常屬于錯(cuò)誤,將被自動(dòng)捕獲,不用 自己進(jìn)行處理。除此之外的異常需要進(jìn)行聲明,并進(jìn)行捕獲或都向上拋出。只能在代碼中忽 略runtimeexception(及其子類(lèi))類(lèi)型的異常,其他類(lèi)型異常的處理都是由編譯器強(qiáng)制實(shí)施 的。runtimeexception代表的編程錯(cuò)誤:1)無(wú)法預(yù)料的錯(cuò)誤;2)作為程序同,應(yīng)該在代碼 中進(jìn)行檢查的錯(cuò)誤。會(huì)捕獲基類(lèi)異常本身以及所有從它派生的異常,如果將基類(lèi)異常放在前面,子類(lèi)異 常放在后面的話(huà),子類(lèi)異常永遠(yuǎn)不會(huì)被捕獲,編輯器會(huì)報(bào)錯(cuò)。unreachable catch block for
is already handled by the catch block for exception。
40.異常處理的一個(gè)重要目標(biāo)就是把錯(cuò)誤處理的代碼同錯(cuò)誤發(fā)生的地點(diǎn)分離。應(yīng)該在下列情 況下使用異常:1)在恰當(dāng)?shù)募?jí)別處理問(wèn)題。(在知道該如何處理的情況下捕獲異常)
2)解 決問(wèn)題并且重新調(diào)用產(chǎn)生異常的方法。3)進(jìn)行少許修被,然后繞過(guò)異常發(fā)生的地方繼續(xù)執(zhí)
java 編程思想第四版 讀書(shū)筆記
行。4)用別的數(shù)據(jù)進(jìn)行計(jì)算,以代替方法預(yù)計(jì)會(huì)返回的值。5)把當(dāng)前運(yùn)行環(huán)境下能做的事 情盡量做完,然后把相同的異常重拋到更高層。6)把當(dāng)前運(yùn)行環(huán)境下能做的事情盡量做完,然后把不同的異常拋到更高層。7)終止程序。8)進(jìn)行簡(jiǎn)化。9)讓類(lèi)庫(kù)和程序更安全。41.字符器:string,stringbuilder,formatter.格式化語(yǔ)法: %[argument_index$][flags][width][.precision]conversion 在默認(rèn)的情況下,數(shù)據(jù)是右對(duì)齊,不過(guò)可以通過(guò)使用“-”標(biāo)志來(lái)改變對(duì)齊方向。42.正則表達(dá)式:意思是“我要插入一個(gè)正則表達(dá)式的反斜線(xiàn),所以其后的字符具有特殊的 意義”。數(shù)字的正則表達(dá)式是:d,普通反斜線(xiàn):,換行:n,制表符:t。要表示“一個(gè) 或多個(gè)之前的表達(dá)式”,使用+。“零個(gè)或多個(gè)”,使用?。(-|+)?:+在正則表達(dá)式中有特殊意 義,必須使用將其轉(zhuǎn)義。string類(lèi)有matches()和split()方法處理正則表達(dá)式。n類(lèi)和matcher類(lèi)來(lái)構(gòu)造正則表達(dá)式對(duì)象。 包,用static e()方法來(lái)編譯正則表達(dá)式生成一個(gè)pattern對(duì)象,再將你想要檢索 的字符串傳入pattern對(duì)象的matcher()方法,它會(huì)生成一個(gè)matcher對(duì)象,最后通過(guò)操作matcher 對(duì)象來(lái)實(shí)現(xiàn)相關(guān)功能。還可以通過(guò)scanner來(lái)完成正則表達(dá)式相關(guān)功能。44.在java中,所有的類(lèi)型轉(zhuǎn)換都是在運(yùn)行進(jìn)進(jìn)行正確性檢查的。e()獲得 class對(duì)象的引用,也可以通過(guò)object類(lèi)的getclass()方法來(lái)獲得。45.使用類(lèi)的準(zhǔn)備工作:1)加載,這是由類(lèi)加載器執(zhí)行,該步驟將查找字節(jié)碼,并從這些字 節(jié)碼中創(chuàng)建一個(gè)class對(duì)象。2)鏈接,將驗(yàn)證類(lèi)中的字節(jié)碼,為靜態(tài)域分配存儲(chǔ)空間,并且 如果必需的話(huà),將解析這個(gè)類(lèi)創(chuàng)建的對(duì)其他類(lèi)的所有引用。3)初始化,如果該類(lèi)具有超類(lèi),則對(duì)其初始化,執(zhí)行靜態(tài)初始化器和靜態(tài)初始化塊。(構(gòu)造器隱式地是靜態(tài)的)。和反射之間的區(qū)別:對(duì)rtti來(lái)說(shuō),文件。而對(duì)于反 射機(jī)制來(lái)說(shuō),.class文件在編譯時(shí)是不可獲取的,文件。47.泛型中t代表類(lèi)型class,要顯式地指明類(lèi)型,必須在點(diǎn)操作符與方法名之間插入尖括號(hào),然后把類(lèi)型置于尖括號(hào)中;如果是在定義該方法的類(lèi)的內(nèi)部,必須在點(diǎn)操作符之前使用this 關(guān)鍵字,如果是使用static的方法,必須在點(diǎn)操作符之前加上類(lèi)名。在泛型代碼內(nèi)部,無(wú)法 獲得任何有關(guān)泛型參數(shù)類(lèi)型的信息。在泛型中創(chuàng)建數(shù)組,tance()。泛 型(
superclass> 48.任何基本類(lèi)型都不能作為類(lèi)型參數(shù),但是可以使用它們的包裝類(lèi),如不能使用 arraylist,但可以使用arraylist 49.異常的分類(lèi):1)error:稱(chēng)為錯(cuò)誤,由java虛擬機(jī)生成并拋出,包括動(dòng)態(tài)鏈接失敗、虛擬 機(jī)錯(cuò)誤等,程序?qū)ζ洳蛔鎏幚恚?)exception:所有異常類(lèi)的父類(lèi),其子類(lèi)對(duì)應(yīng)了各種各樣可 能出現(xiàn)的異常事件,一般需要用戶(hù)顯示的聲明或捕獲;
3)runtime exception:一類(lèi)特殊的異常,如被0除、數(shù)據(jù)下標(biāo)超范圍等,其產(chǎn)生比較頻繁,處理麻煩,如果顯式的聲明或捕獲將會(huì)對(duì) 程序可讀性和運(yùn)行效率影響很大。因此由系統(tǒng)自動(dòng)檢測(cè)并將它們交給缺省的異常處理程序(用戶(hù)可不必對(duì)其處理)。50.使用自定義異常一般步驟:1)ion類(lèi)聲明自己的異常類(lèi);2)在 方法適當(dāng)?shù)奈恢蒙勺远x異常的實(shí)例,并用throw語(yǔ)句拋出; 在方法的聲明部分用throws 3)語(yǔ)句聲明該方法可能拋出的異常。
二 專(zhuān)項(xiàng)復(fù)習(xí)
1.容器 2.正則表達(dá)式
java 編程思想第四版 讀書(shū)筆記
3.設(shè)計(jì)模式 4.異常 5.泛型 6.反射 7.多線(xiàn)程
常用包(加粗是抽象類(lèi),斜體是接口,普通是類(lèi))三 j2se 常用包(加粗是抽象類(lèi),斜體是接口,普通是類(lèi))
提供利用 java 編程語(yǔ)言進(jìn)行程序設(shè)計(jì)的基礎(chǔ)類(lèi)。process、processbuilder、runtime、system、string、object、class、classloader、math、compiler、thread、threadgroup、runnable、threadlocal、inheritablethreadlocal、package .util arraylist、arrays、collection、collections、linkedlist、hashset、treeset、iterator、listiterator、map、hashmap、treemap、comparator 歷史遺留的類(lèi):dictionary、hashtable、properties、stack、vector、enumeration 使用迭代函數(shù)的步驟:1)通過(guò)調(diào)用類(lèi)集的iterator()或listiterator()方法獲得對(duì)類(lèi)集頭的迭代函 數(shù);2)建立一個(gè)調(diào)用hasnext()方法的循環(huán),只要hasnext()返回true,就進(jìn)行循環(huán)迭代;3)在循環(huán)內(nèi)部,通過(guò)調(diào)用next()方法來(lái)得到每一個(gè)元素。gregoriancalendar、timezone、simpletimezone、locale、dateformat、bitset、calendar、simpledateformat、random、observer、observable、timer、timertask gregoriancalendar定義了兩個(gè)域:ad和bc。它們代表由公歷定義的兩個(gè)紀(jì)元。bc公元前,ad公元后 inputstream、outputstream reader、writer outputstream、reader writer、fileinputstream、fileoutputstream、inputstream outputstream reader writer bytearrayinputstream、bytearrayoutputstream、filteroutputstream、filterinputstream、bufferedinputstream、bufferedoutputstream、sequenceinputstream、printstream、randomaccessfile filereader、filewriter、chararrayreader、chararraywriter、bufferedreader、bufferedwriter、printwriter objectinputstream、izable 或 alizable 接口的對(duì)象才能從流讀取。 inetaddress、url、urlconnection java中有兩類(lèi)tcp套接字。一種是服務(wù)器端的,另一種是客戶(hù)端的。serversocket類(lèi)設(shè) 計(jì)成在等待客戶(hù)建立連接之前不做任何事的“監(jiān)聽(tīng)器”。socket類(lèi)為建立連向服務(wù)器套接 字以及啟動(dòng)協(xié)議交換而設(shè)計(jì); 文件。所以,http:/// 與http:/// 是相同 的。java通過(guò)兩個(gè)類(lèi)實(shí)現(xiàn)udp協(xié)議頂層的數(shù)據(jù)報(bào):datagrampacket對(duì)象是數(shù)據(jù)容器,datagramsocket是用來(lái)發(fā)送和接受datagrampackets的機(jī)制。
版權(quán)聲明:本文內(nèi)容由互聯(lián)網(wǎng)用戶(hù)自發(fā)貢獻(xiàn),該文觀點(diǎn)僅代表作者本人。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如發(fā)現(xiàn)本站有涉嫌抄襲侵權(quán)/違法違規(guī)的內(nèi)容, 請(qǐng)發(fā)送郵件至 yyfangchan@163.com (舉報(bào)時(shí)請(qǐng)帶上具體的網(wǎng)址) 舉報(bào),一經(jīng)查實(shí),本站將立刻刪除