摘要: DOM4J是dom4j.org出品的一個(gè)開源XML解析包,它的網(wǎng)站中這樣定義:
Dom4j is an easy to use, open source library for working with XML, XPath and XSLT on the Java platform using the Java Collections Framework and with full support for DOM, SAX and JAXP.
閱讀全文
從Java1.1開始引入了內(nèi)部類以來,它就引起了人們的激烈爭(zhēng)論。其實(shí)任何優(yōu)秀的語言特性用得不好就是濫用,內(nèi)部類用得不好就會(huì)導(dǎo)致代碼像迷宮一樣,導(dǎo)致出現(xiàn)毫無重用的綜合征。
1、內(nèi)部類分為成員內(nèi)部類、靜態(tài)嵌套類、方法內(nèi)部類、匿名內(nèi)部類。
幾種內(nèi)部類的共性:
A、內(nèi)部類仍然是一個(gè)獨(dú)立的類,在編譯之后會(huì)內(nèi)部類會(huì)被編譯成獨(dú)立的.class文件,但是前面冠以外部類的類命和$符號(hào)。
B、內(nèi)部類不能用普通的方式訪問。內(nèi)部類是外部類的一個(gè)成員,因此內(nèi)部類可以自由地訪問外部類的成員變量,無論是否是private的。
2、成員內(nèi)部類:形式如下
class Outer {
class Inner{}
}
編譯上述代碼會(huì)產(chǎn)生兩個(gè)文件:Outer.class和Outer$Inner.class。
成員內(nèi)部類內(nèi)不允許有任何靜態(tài)聲明!下面代碼不能通過編譯。
class Inner{
static int a = 10;
}
能夠訪問成員內(nèi)部類的唯一途徑就是通過外部類的對(duì)象!
A、從外部類的非靜態(tài)方法中實(shí)例化內(nèi)部類對(duì)象。
class Outer {
private int i = 10;
public void makeInner(){
Inner in = new Inner();
in.seeOuter();
}
class Inner{
public void seeOuter(){
System.out.print(i);
}
}
}
表面上,我們并沒有創(chuàng)建外部類的對(duì)象就實(shí)例化了內(nèi)部類對(duì)象,和上面的話矛盾。事實(shí)上,如果不創(chuàng)建外部類對(duì)象也就不可能調(diào)用makeInner()方法,所以到頭來還是要?jiǎng)?chuàng)建外部類對(duì)象的。
你可能試圖把makeInner()方法修飾為靜態(tài)方法,即static public void makeInner()。這樣不創(chuàng)建外部類就可以實(shí)例化外部類了!但是在一個(gè)靜態(tài)方法里能訪問非靜態(tài)成員和方法嗎?顯然不能。它沒有this引用。沒能跳出那條規(guī)則!但是如果在這個(gè)靜態(tài)方法中實(shí)例化一個(gè)外部類對(duì)象,再用這個(gè)對(duì)象實(shí)例化外部類呢?完全可以!也就是下一條的內(nèi)容。
B、從外部類的靜態(tài)方法中實(shí)例化內(nèi)部類對(duì)象。
class Outer {
private int i = 10;
class Inner{
public void seeOuter(){
System.out.print(i);
}
}
public static void main(String[] args) {
Outer out = new Outer();
Outer.Inner in = out.new Inner();
//Outer.Inner in = new Outer().new Inner();
in.seeOuter();
}
}
被注釋掉的那行是它上面兩行的合并形式,一條簡潔的語句。
對(duì)比一下:在外部類的非靜態(tài)方法中實(shí)例化內(nèi)部類對(duì)象是普通的new方式:Inner in = new Inner();
在外部類的靜態(tài)方法中實(shí)例化內(nèi)部類對(duì)象,必須先創(chuàng)建外部類對(duì)象:Outer.Inner in = new Outer().new Inner();
C、內(nèi)部類的this引用。
普通的類可以用this引用當(dāng)前的對(duì)象,內(nèi)部類也是如此。但是假若內(nèi)部類想引用外部類當(dāng)前的對(duì)象呢?用“外部類名”.this;的形式,如下例的Outer.this。
class Outer {
class Inner{
public void seeOuter(){
System.out.println(this);
System.out.println(Outer.this);
}
}
}
D、成員內(nèi)部類的修飾符。
對(duì)于普通的類,可用的修飾符有final、abstract、strictfp、public和默認(rèn)的包訪問。
但是成員內(nèi)部類更像一個(gè)成員變量和方法。
可用的修飾符有:final、abstract、public、private、protected、strictfp和static。
一旦用static修飾內(nèi)部類,它就變成靜態(tài)內(nèi)部類了。
3、方法內(nèi)部類。
顧名思義,把類放在方法內(nèi)。
class Outer {
public void doSomething(){
class Inner{
public void seeOuter(){
}
}
}
}
A、方法內(nèi)部類只能在定義該內(nèi)部類的方法內(nèi)實(shí)例化,不可以在此方法外對(duì)其實(shí)例化。
B、方法內(nèi)部類對(duì)象不能使用該內(nèi)部類所在方法的非final局部變量。
因?yàn)榉椒ǖ木植孔兞课挥跅I?,只存在于該方法的生命期?nèi)。當(dāng)一個(gè)方法結(jié)束,其棧結(jié)構(gòu)被刪除,局部變量成為歷史。但是該方法結(jié)束之后,在方法內(nèi)創(chuàng)建的內(nèi)部類對(duì)象可能仍然存在于堆中!例如,如果對(duì)它的引用被傳遞到其他某些代碼,并存儲(chǔ)在一個(gè)成員變量內(nèi)。正因?yàn)椴荒鼙WC局部變量的存活期和方法內(nèi)部類對(duì)象的一樣長,所以內(nèi)部類對(duì)象不能使用它們。
下面是完整的例子:
class Outer {
public void doSomething(){
final int a =10;
class Inner{
public void seeOuter(){
System.out.println(a);
}
}
Inner in = new Inner();
in.seeOuter();
}
public static void main(String[] args) {
Outer out = new Outer();
out.doSomething();
}
}
C、方法內(nèi)部類的修飾符。
與成員內(nèi)部類不同,方法內(nèi)部類更像一個(gè)局部變量。
可以用于修飾方法內(nèi)部類的只有final和abstract。
D、靜態(tài)方法內(nèi)的方法內(nèi)部類。
靜態(tài)方法是沒有this引用的,因此在靜態(tài)方法內(nèi)的內(nèi)部類遭受同樣的待遇,即:只能訪問外部類的靜態(tài)成員。
4、匿名內(nèi)部類。
顧名思義,沒有名字的內(nèi)部類。表面上看起來它們似乎有名字,實(shí)際那不是它們的名字。
A、繼承式的匿名內(nèi)部類。
class Car {
public void drive(){
System.out.println("Driving a car!");
}
}
class Test{
public static void main(String[] args) {
Car car = new Car(){
public void drive(){
System.out.println("Driving another car!");
}
};
car.drive();
}
}
結(jié)果輸出了:Driving another car! Car引用變量不是引用Car對(duì)象,而是Car匿名子類的對(duì)象。
建立匿名內(nèi)部類的關(guān)鍵點(diǎn)是重寫父類的一個(gè)或多個(gè)方法。再強(qiáng)調(diào)一下,是重寫父類的方法,而不是創(chuàng)建新的方法。因?yàn)橛酶割惖囊貌豢赡苷{(diào)用父類本身沒有的方法!創(chuàng)建新的方法是多余的。簡言之,參考多態(tài)。
B、接口式的匿名內(nèi)部類。
interface Vehicle {
public void drive();
}
class Test{
public static void main(String[] args) {
Vehicle v = new Vehicle(){
public void drive(){
System.out.println("Driving a car!");
}
};
v.drive();
}
}
上面的代碼很怪,好像是在實(shí)例化一個(gè)接口。事實(shí)并非如此,接口式的匿名內(nèi)部類是實(shí)現(xiàn)了一個(gè)接口的匿名類。而且只能實(shí)現(xiàn)一個(gè)接口。
C、參數(shù)式的匿名內(nèi)部類。
class Bar{
void doStuff(Foo f){}
}
interface Foo{
void foo();
}
class Test{
static void go(){
Bar b = new Bar();
b.doStuff(new Foo(){
public void foo(){
System.out.println("foofy");
}
});
}
}
5、靜態(tài)嵌套類。
從技術(shù)上講,靜態(tài)嵌套類不屬于內(nèi)部類。因?yàn)閮?nèi)部類與外部類共享一種特殊關(guān)系,更確切地說是對(duì)實(shí)例的共享關(guān)系。而靜態(tài)嵌套類則沒有上述關(guān)系。它只是位置在另一個(gè)類的內(nèi)部,因此也被稱為頂級(jí)嵌套類。
靜態(tài)的含義是該內(nèi)部類可以像其他靜態(tài)成員一樣,沒有外部類對(duì)象時(shí),也能夠訪問它。靜態(tài)嵌套類不能訪問外部類的成員和方法。
class Outer{
static class Inner{}
}
class Test {
public static void main(String[] args){
Outer.Inner n = new Outer.Inner();
}
}
一、常用輸出格式
%c 列出logger名字空間的全稱,如加上{<層數(shù)>}表示出從最內(nèi)層算起的指定層數(shù)的名字空間
%X 按MDC(Mapped Diagnostic Context,線程映射表)輸出日志。通常用于多個(gè)客戶端連接同一臺(tái)服務(wù)器,方便服務(wù)器區(qū)分是那個(gè)客戶端訪問留下來的日志。
%p 日志信息級(jí)別
%d %d{<日期格式>}:日志信息產(chǎn)生時(shí)間,使用ISO8601定義的日期格式
%C 日志信息所在地(全限類名)
%m 產(chǎn)生的日志具體信息
%n 輸出日志信息換行
%F 顯示調(diào)用logger的源文件名
%l 輸出日志事件的發(fā)生位置,包括類目名、發(fā)生的線程,以及在代碼中的行數(shù)
%L 顯示調(diào)用logger的代碼行
%M 顯示調(diào)用logger的方法名
%r 顯示從程序啟動(dòng)時(shí)到記錄該條日志時(shí)已經(jīng)經(jīng)過的毫秒數(shù)
%t 輸出產(chǎn)生該日志事件的線程名
%% 顯示一個(gè)
二、log4j.properties
#控制包中日志輸出級(jí)別
log4j.logger.org.apache.struts = debug
# 應(yīng)用于控制臺(tái)
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.Threshold=DEBUG
log4j.appender.CONSOLE.Target=System.out
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=[framework] %d - %-4r [%t] %-5p %c %x - %m%n
#log4j.appender.CONSOLE.layout.ConversionPattern=[start]%d{DATE}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[THREAD] n%c[CATEGORY]%n%m[MESSAGE]%n%n
#應(yīng)用于文件
log4j.appender.FILE=org.apache.log4j.FileAppender
log4j.appender.FILE.File=file.log
log4j.appender.FILE.Append=false
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.ConversionPattern=[framework] %d - %-4r [%t] %-5p %c %x - %m%n
# Use this layout for LogFactor 5 analysis
# 應(yīng)用于文件回滾
log4j.appender.ROLLING_FILE=org.apache.log4j.RollingFileAppender
log4j.appender.ROLLING_FILE.Threshold=ERROR
log4j.appender.ROLLING_FILE.File=rolling.log
log4j.appender.ROLLING_FILE.Append=true
log4j.appender.ROLLING_FILE.MaxFileSize=100KB
log4j.appender.ROLLING_FILE.MaxBackupIndex=10
log4j.appender.ROLLING_FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.ROLLING_FILE.layout.ConversionPattern=[framework] %d - %-4r [%t] %-5p %c %x - %m%n
#應(yīng)用于socket
log4j.appender.SOCKET=org.apache.log4j.net.SocketAppender
log4j.appender.SOCKET.RemoteHost=localhost
log4j.appender.SOCKET.Port=5001
log4j.appender.SOCKET.LocationInfo=true
# Set up for Log Facter 5
log4j.appender.SOCKET.layout=org.apache.log4j.PatternLayout
log4j.appender.SOCET.layout.ConversionPattern=[start]%d{DATE}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[THREAD]%n%c[CATEGORY]%n%m[MESSAGE]%n%n
# Log Factor 5 Appender
log4j.appender.LF5_APPENDER=org.apache.log4j.lf5.LF5Appender
log4j.appender.LF5_APPENDER.MaxNumberOfRecords=2000
# 發(fā)送日志給郵件
log4j.appender.MAIL=org.apache.log4j.net.SMTPAppender
log4j.appender.MAIL.Threshold=FATAL
log4j.appender.MAIL.BufferSize=10
log4j.appender.MAIL.From=web@www.wuset.com
log4j.appender.MAIL.SMTPHost=www.wusetu.com
log4j.appender.MAIL.Subject=Log4J Message
log4j.appender.MAIL.To=web@www.wusetu.com
log4j.appender.MAIL.layout=org.apache.log4j.PatternLayout
log4j.appender.MAIL.layout.ConversionPattern=[framework] %d - %-4r [%t] %-5p %c %x - %m%n
# 用于數(shù)據(jù)庫
log4j.appender.DATABASE=org.apache.log4j.jdbc.JDBCAppender
log4j.appender.DATABASE.URL=jdbc:mysql://localhost:3306/test
log4j.appender.DATABASE.driver=com.mysql.jdbc.Driver
log4j.appender.DATABASE.user=root
log4j.appender.DATABASE.password=
log4j.appender.DATABASE.sql=INSERT INTO LOG4J (Message) VALUES ('[framework] %d - %-4r [%t] %-5p %c %x - %m%n')
log4j.appender.DATABASE.layout=org.apache.log4j.PatternLayout
log4j.appender.DATABASE.layout.ConversionPattern=[framework] %d - %-4r [%t] %-5p %c %x - %m%n
#每日回滾日志文件
log4j.appender.A1=org.apache.log4j.DailyRollingFileAppender
log4j.appender.A1.File=SampleMessages.log4j
log4j.appender.A1.DatePattern=yyyyMMdd-HH'.log4j'
log4j.appender.A1.layout=org.apache.log4j.xml.XMLLayout
#自定義Appender
log4j.appender.im = net.cybercorlin.util.logger.appender.IMAppender
log4j.appender.im.host = mail.cybercorlin.net
log4j.appender.im.username = username
log4j.appender.im.password = password
log4j.appender.im.recipient = corlin@cybercorlin.net
log4j.appender.im.layout=org.apache.log4j.PatternLayout
log4j.appender.im.layout.ConversionPattern =[framework] %d - %-4r [%t] %-5p %c %x - %m%n
1.你需要精通面向?qū)ο蠓治雠c設(shè)計(jì)(OOA/OOD)、涉及模式(GOF,J2EEDP)以及綜合模式。你應(yīng)該十分了解UML,尤其是class,object,interaction以及statediagrams。
2.你需要學(xué)習(xí)JAVA語言的基礎(chǔ)知識(shí)以及它的核心類庫(collections,serialization,streams,networking, multithreading,reflection,event,handling,NIO,localization,以及其他)。
3.你應(yīng)該了解JVM,classloaders,classreflect,以及垃圾回收的基本工作機(jī)制等。你應(yīng)該有能力反編譯一個(gè)類文件并且明白一些基本的匯編指令。
4.如果你將要寫客戶端程序,你需要學(xué)習(xí)WEB的小應(yīng)用程序(applet),必需掌握GUI設(shè)計(jì)的思想和方法,以及桌面程序的SWING,AWT, SWT。你還應(yīng)該對(duì)UI部件的JAVABEAN組件模式有所了解。JAVABEANS也被應(yīng)用在JSP中以把業(yè)務(wù)邏輯從表現(xiàn)層中分離出來。
5.你需要學(xué)習(xí)java數(shù)據(jù)庫技術(shù),如JDBCAPI并且會(huì)使用至少一種persistence/ORM構(gòu)架,例如Hibernate,JDO, CocoBase,TopLink,InsideLiberator(國產(chǎn)JDO紅工廠軟件)或者iBatis。
6.你還應(yīng)該了解對(duì)象關(guān)系的阻抗失配的含義,以及它是如何影響業(yè)務(wù)對(duì)象的與關(guān)系型數(shù)據(jù)庫的交互,和它的運(yùn)行結(jié)果,還需要掌握不同的數(shù)據(jù)庫產(chǎn)品運(yùn)用,比如:oracle,mysql,mssqlserver。
7.你需要學(xué)習(xí)JAVA的沙盒安全模式(classloaders,bytecodeverification,managers,policyandpermissions,
codesigning, digitalsignatures,cryptography,certification,Kerberos,以及其他)還有不同的安全/認(rèn)證 API,例如JAAS(JavaAuthenticationandAuthorizationService),JCE (JavaCryptographyExtension),JSSE(JavaSecureSocketExtension),以及JGSS (JavaGeneralSecurityService)。
8.你需要學(xué)習(xí)Servlets,JSP,以及JSTL(StandardTagLibraries)和可以選擇的第三方TagLibraries。
9.你需要熟悉主流的網(wǎng)頁框架,例如JSF,Struts,Tapestry,Cocoon,WebWork,以及他們下面的涉及模式,如MVC/MODEL2。
10.你需要學(xué)習(xí)如何使用及管理WEB服務(wù)器,例如tomcat,resin,Jrun,并且知道如何在其基礎(chǔ)上擴(kuò)展和維護(hù)WEB程序。
11.你需要學(xué)習(xí)分布式對(duì)象以及遠(yuǎn)程API,例如RMI和RMI/IIOP。
12.你需要掌握各種流行中間件技術(shù)標(biāo)準(zhǔn)和與java結(jié)合實(shí)現(xiàn),比如Tuxedo、CROBA,當(dāng)然也包括javaEE本身。
13.你需要學(xué)習(xí)最少一種的XMLAPI,例如JAXP(JavaAPIforXMLProcessing),JDOM(JavaforXMLDocumentObjectModel),DOM4J,或JAXR(JavaAPIforXMLRegistries)。
14.你應(yīng)該學(xué)習(xí)如何利用JAVAAPI和工具來構(gòu)建WebService。例如JAX-RPC(JavaAPIforXML/RPC),SAAJ (SOAPwithAttachmentsAPIforJava),JAXB(JavaArchitectureforXMLBinding),JAXM(JavaAPIforXMLMessaging), JAXR(JavaAPIforXMLRegistries),或者JWSDP(JavaWebServicesDeveloperPack)。
15.你需要學(xué)習(xí)一門輕量級(jí)應(yīng)用程序框架,例如Spring,PicoContainer,Avalon,以及它們的IoC/DI風(fēng)格(setter,constructor,interfaceinjection)。
16.你需要熟悉不同的J2EE技術(shù),例如JNDI(JavaNamingandDirectoryInterface),JMS (JavaMessageService),JTA/JTS(JavaTransactionAPI/JavaTransactionService),JMX (JavaManagementeXtensions),以及JavaMail。
17.你需要學(xué)習(xí)企業(yè)級(jí)JavaBeans(EJB)以及它們的不同組件模式:Stateless/StatefulSessionBeans,EntityBeans(包含Bean- ManagedPersistence[BMP]或者Container-ManagedPersistence[CMP]和它的EJB-QL),或者 Message-DrivenBeans(MDB)。
18.你需要學(xué)習(xí)如何管理與配置一個(gè)J2EE應(yīng)用程序服務(wù)器,如WebLogic,JBoss等,并且利用它的附加服務(wù),例如簇類,連接池以及分布式處理支援。你還需要了解如何在它上面封裝和配置應(yīng)用程序并且能夠監(jiān)控、調(diào)整它的性能。
19.你需要熟悉面向方面的程序設(shè)計(jì)以及面向?qū)傩缘某绦蛟O(shè)計(jì)(這兩個(gè)都被很容易混淆的縮寫為AOP),以及他們的主流JAVA規(guī)格和執(zhí)行。例如AspectJ和AspectWerkz。
20.你需要熟悉對(duì)不同有用的API和frame work等來為你服務(wù)。例如Log4J(logging/tracing),Quartz (scheduling),JGroups(networkgroupcommunication),JCache(distributedcaching), Lucene(full-textsearch),JakartaCommons等等。
21.如果你將要對(duì)接或者正和舊的系統(tǒng)或者本地平臺(tái),你需要學(xué)習(xí)JNI (JavaNativeInterface) and JCA (JavaConnectorArchitecture)。
22.你需要熟悉JINI技術(shù)以及與它相關(guān)的分布式系統(tǒng),比如掌握CROBA。
23.你需要JavaCommunityProcess(JCP)以及他的不同JavaSpecificationRequests(JSRs),例如Portlets(168),JOLAP(69),DataMiningAPI(73),等等。
24.你應(yīng)該熟練掌握一種JAVAIDE例如sunOne,netBeans,IntelliJIDEA或者Eclipse。(有些人更喜歡VI或EMACS來編寫文件。隨便你用什么了:)
25.JAVA(精確的說是有些配置)是冗長的,它需要很多的人工代碼(例如EJB),所以你需要熟悉代碼生成工具,例如XDoclet。
26.你需要熟悉一種單元測(cè)試體系(JNunit),并且學(xué)習(xí)不同的生成、部署工具(Ant,Maven)。
27.你需要熟悉一些在JAVA開發(fā)中經(jīng)常用到的軟件工程過程。例如RUP(RationalUnifiedProcess)andAgilemethodologies。
28.你需要能夠深入了解加熟練操作和配置不同的操作系統(tǒng),比如GNU/linux,sunsolaris,macOS等,做為跨平臺(tái)軟件的開發(fā)者。
29.你還需要緊跟java發(fā)展的步伐,比如現(xiàn)在可以深入的學(xué)習(xí)javaME,以及各種java新規(guī)范,技術(shù)的運(yùn)用,如新起的web富客戶端技術(shù)。
30.你必需要對(duì)opensource有所了解,因?yàn)橹辽賘ava的很多技術(shù)直接是靠開源來驅(qū)動(dòng)發(fā)展的,如java3D技術(shù)。