标签: java

  • JAVA“高手”基礎素養

    世界上並沒有成為高手的捷徑,但一些基本原則是可以遵循的。

    1、紮實的基礎

    數據結構、離散數學、編譯原理,這些是所有計算機科學的基礎,如果不掌握它們,很難寫出高水平的程序。程序人人都會寫,但當你發現寫到一定程度很難再提高的時候,就應該想想是不是要回過頭來學學這些最基本的理論。不要一開始就去學OOP,即使你再精通OOP,遇到一些基本算法的時候可能也會束手無策。因此多讀一些計算機基礎理論方面的書籍是非常有必要的。

    2、豐富的想像力

    不要拘泥於固定的思維方式,遇到問題的時候要多想幾種解決問題的方案,試試別人從沒想過的方法。豐富的想像力是建立在豐富的知識的基礎上,除計算機以外,多涉獵其他的學科,比如天文、物理、數學等等。開闊的思維對程序員來說很重要。

    3、最簡單的是最好的

    …..

    (更多…)

  • Oracle收購Sun之後:有關Java未來的三個關鍵問題

    我們都已經聽說了有關為什麼Oracle收購Sun的一些猜測:
         Oracle一直都想和IBM站在同一水平線上。他們想要被看作是一個完整的供應商,提供應用程序,平台和數據庫。如果你想要,那就是一站式服務。

         Oracle已經佔據了應用程序和數據庫的大部分市場。為了保持在這一領域的主要地位,他們想要擴展並深入到硬件業務中。

        收購是一項長期的防禦舉動以回應微軟收購SAP的謠言。

        雖然收購的原因對很多人來說是很重要的,但是對於我來說最重要的是會在Sun這15年中所創建和服務的Java技術上發生什麼事情。我經常會寫到”Java is COBOL” ,因為今天幾乎所有的商業都有一些Java要做的事情。謠言在應用程序開發行業中漫天飛,但是我們早知道塵埃會落定,故事將會結束。這不意味著我們不能用歷史來引導我們預測未來。 Ruby能否成為第二個Java?

        從純粹的Java角度來看一看Oracle所得到的,這三個關鍵問題是:

         Java Community Process (JCP)會繼續存在嗎?

         Apache Software Foundation (ASF)和Sun之間的爭端會解決嗎?

         Oracle會通過為JDK扣交TCKs而取得Java IP嗎?

         JCP會繼續存在嗎?

         Oracle是JCP的高級成員,而且他們已經提交了80多個Java Specification Requests (JSRs)。儘管有這個長期的參與承諾,Oracle表示——和其他的供應商和參與者一起——JCP過程需要變得更開放,透明並且廠商中立。特別是在2007年12月12日的時候,Oracle提出了這個:Resolution 1 (由Oracle提議,第二個是由BEA提出) .

         “Executive Committee感覺到JCP變成一個開放獨立並且是廠商中立的標準組織,那裡所有的成員都參與公平競爭,具體有以下特點:

        成員基金開發和管理費用

        一個法人實體,有法律,理事會和董事成員等等。

        一個新的,簡單的IPR Policy(知識產權政策)允許更大範圍的執行。

        嚴格的兼容性要求

        致力於促進Java編程模式

        此外,EC將在對Java Community干預最小的情況下,盡快實施這個計劃以確保這樣的過渡盡快的實施。 “

        所以我們希望Oracle能繼續JCP,但是它可能變成一個完全不同的JCP.如果Oracle成功的實施了所期望的轉變,結果會是非常有趣的而且具有廣泛的影響。特別有趣的是看到Oracle如何實施這些變革。那將是第一個跡象表明Oracle將如何同Java工作。

         Apache Software Foundation (ASF)和Sun之間的爭端會解決嗎?客戶端Java的革命性飛躍圍繞Apache和Sun爭論的主要問題是多種多樣的,但是這裡有一個對這些事件的簡短總結:

         Apache Harmony Project目的是創建一個ASF授權的模塊化虛擬機(VM)和基於Java SE 5.0版本的JDK.

         Sun的JDK開源和OpenJDK項目。

        要成為一個認證的JDK,Harmony需要通過Sun的Technology Compatibility Kits(TCKs)。

         Sun說到Harmony是基於舊的JDK5.0而且不是在最新的JDK6.0上,所以認證過程停滯了,Harmony Project也懸而未決。

        到今天,OpenJDK管理委員會也沒有解決這個爭端。 Oracle如何處理這個情況是他們如何管理Java程序的第二個晴雨表。

         Oracle會通過為JDK扣交TCKs而取得Java IP嗎?

        在JDK認證中涉及了很多法律問題會成為Java的大量蠕蟲。例如,除非你為OpenJDK通過TCK,否則你不獲得Java Intellectual Property (IP)的權力——即你沒有認證的JDK.

        由於你沒有Java SE7的一套規範,而且Sun也沒有購買一個,所有沒有辦法擁有一個官方的OpenJDK 7.Oracle會採取同樣的辦法,而且不會發布一個規範或是TCKs,這樣將IP在內部保持。

        總結

        如你所見,這三個問題都有所關聯,每個答案本身有不同的水平和層次,例如:

         JCP肯能會繼續存在,但是它可能在指定技術方向上承擔不同的作用。

        管理上的這種差異為ASF問題提供一個簡單的解決方案,讓它們成為泛黃的記憶。

         Oracle可能會推出一個新的JDK規範連同TCKs一起,完全實現一個開放的JDK承諾。

        如何發揮這些因素將讓Java developmer community清楚的知道Oracle如何運行Java.

  • 淺談:Java代碼的優化策略

    1.如何使用Exception
    Exception降低性能。一個異常拋出首先需要創建一個新的對象。 Throwable接口中的構造器調用名為fillInStackTrace()的本地方法。這個方法負責巡檢棧的整個框架來收集跟踪信息。這樣無論何時有異常拋出,它要求虛擬機裝載調用棧,因為一個新的對像在中部被創建。

    異常應當僅用於有錯誤發生時,而不要控制流。

    2.不要兩次初始化變量

    Java通過調用獨特的類構造器默認地初始化變量為一個已知的值。所有的對像被設置成null,integers (byte, short, int, long)被設置成0,float和double設置成0.0,Boolean變量設置成false。這對那些擴展自其它類的類尤其重要,這跟使用一個新的關鍵詞創建一個對象時所有一連串的構造器被自動調用一樣。

    3.在任何可能的地方讓類為Final

    標記為final的類不能被擴展。在《核心Java API》中有大量這個技術的例子,諸如java.lang.String。將String類標記為final阻止了開發者創建他們自己實現的長度方法。

    更深入點說,如果類是final的,所有類的方法也是final的。 Java編譯器可能會內聯所有的方法(這依賴於編譯器的實現)。在我的測試裡,我已經看到性能平均增加了50%。

    4.在任何可能的地方使用局部變量

    屬於方法調用部分的自變量和聲明為此調用一部分的臨時變量存儲在棧中,這比較快。諸如static,實例(instance)變量和新的對象創建在堆中,這比較慢。局部變量的更深入優化依賴於你正在使用的編譯器或虛擬機。

    5.停止小聰明

    很多開發人員在腦子中編寫可複用和靈活的代碼,而有時候在他們的程序中就產生額外的開銷。曾經或者另外的時候他們編寫了類似這樣的代碼:

    public void doSomething(File file) {
    FileInputStream fileIn = new FileInputStream(file);
    // do something

    他夠靈活,但是同時他們也產生了更多的開銷。這個主意背後做的事情是操縱一個InputStream,而不是一個文件,因此它應該重寫如下:

    public void doSomething(InputStream inputStream){
    // do something

    6.乘法和除法

    我有太多的東東適用於摩爾法則——它聲明CPU功率每年成倍增長。 “摩爾法則”表明每年由開發者所寫的差勁的代碼數量三倍增加,劃去了摩爾法則的任何好處。

    考慮下面的代碼:

    for (val = 0; val < 100000; val +=5) { shiftX = val 8; myRaise = val 2; }

    如果我們狡猾的利用位移(bit),性能將會六倍增加。這是重寫的代碼:

    for (val = 0; val < 100000; val += 5) { shiftX = val << 3; myRaise = val << 1; }

    代替了乘以8,我們使用同等效果的左移3位。每一個移動相當於乘以2,變量myRaise對此做了證明。同樣向右移位相當於除以2,當然這會使執行速度加快,但可能會使你的東東以後難於理解;所以這只是個建議

    7.用代碼有效處理內存溢出

    OutOfMemoryError是由於內存不夠後普遍會遇到的問題,下面一段代碼能有效判斷內存溢出錯誤,並在內存溢出發生時有效回收內存

    通過該方法可以聯想到有效管理連接池溢出,道理等同。

    import Java.util.*;
    public class DataServer
    {
    private Hashtable data = new Hashtable();
    public Object get (String key)
    {
    Object obj = data.get (key);
    if (obj == null)
    {
    System.out.print (key + “ ”);
    try
    {
    // simulate getting lots of data
    obj = new Double[1000000];
    data.put (key, obj);
    }
    catch (OutOfMemoryError e)
    {
    System.out.print (“No Memory! ”);
    flushCache();
    obj = get (key);// try again
    }
    }
    return (obj);
    }
    public void flushCache()
    {
    System.out.println (“Clearing cache”);
    data.clear();
    }
    public static void main (String[] args)
    {
    DataServer ds = new DataServer();
    int count = 0;
    while (true) // infinite loop for test
    ds.get (“” count+);
    }
    }

    8. Lazy Loading (Lazy evaluation)在需要裝入的時候才裝入

    static public long
    factorial( int n ) throws IllegalArgumentException
    {
    IllegalArgumentException illegalArgumentException =
    new IllegalArgumentException( “must be >= 0” );
    if( n < 0 ) {
    throw illegalArgumentException ;
    } else if( ( n 0 ) || ( n 1 ) ) {
    return( 1 );
    } else (
    return( n * factorial( n – 1 ) ) ;
    }

    優化後代碼

    static public long
    factorial( int n ) throws IllegalArgumentException
    {
    if( n < 0 ) {
    throw new IllegalArgumentException( “must be >= 0” );
    } else if( ( n 0 ) || ( n 1 ) ) {
    return( 1 );
    } else (
    return( n * factorial( n – 1 ) ) ;
    }

    9.異常在需要拋出的地方拋出,try catch能整合就整合

    try {
    some.method1(); // Difficult for Javac
    } catch( method1Exception e ) { // and the JVM runtime
    // Handle exception 1 // to optimize this
    } // code
    try {
    some.method2();
    } catch( method2Exception e ) {
    // Handle exception 2
    }
    try {
    some.method3();
    } catch( method3Exception e ) {
    // Handle exception 3
    }

    已下代碼更容易被編譯器優化

    try {
    some.method1(); // Easier to optimize
    some.method2();
    some.method3();
    } catch( method1Exception e ) {
    // Handle exception 1
    } catch( method2Exception e ) {
    // Handle exception 2
    } catch( method3Exception e ) {
    // Handle exception 3
    }

    10. For循環的優化

    Replace…
    for( int i = 0; i < collection.size(); i++ ) {

    }
    with…
    for( int i = 0, n = collection.size(); i < n; i++ ) {

    }

    11.字符串操作優化

    在對字符串實行+操作時,最好用一條語句

    // Your source code looks like…
    String str = “profit = revenue( ” revenue
    “ – cost( ” cost ““;
    //編譯方法
    String str = new StringBuffer( ).append( “profit = revenue( “ ).
    append( revenue ).append( “ – cost( “ ).
    append( cost ).append( ““ ).toString( );
    在循環中對字符串操作時改用StringBuffer.append()方法
    String sentence = “”;
    for( int i = 0; i < wordArray.length; i++ ) {
    sentence += wordArray[ i ];
    }

    優化為

    StringBuffer buffer = new StringBuffer( 500 );
    for( int i = 0; i < wordArray.length; i++ ) {
    buffer.append( wordArray[ i ] );
    }
    String sentence = buffer.toString( );

    12.對象重用(特別對於大對象來說)

    public
    class Point
    {
    public int x;
    public int y;
    public Point( )
    {
    this( 0, 0 );
    }
    }

    優化為:

    public class Component
    {
    private int x;
    private int y;
    public Point getPosition( )
    {
    Point rv = new Point( ); // Create a new Point
    rv.x = x; // Update its state
    rv.y = y;
    return rv;
    }
    }
    // Process an array of Component positions…
    for( int i = 0; i < componentArray.length; i++ ) {
    Point position = componentArray[i].getPosition( );
    // Process position value…
    // Note: A Point object is created for each iteration
    // of the loop…
    }

    可再次優化,僅使用一個類對象:)

    public
    class Component
    {
    private int x;
    private int y;
    public Point getPosition( Point rv )
    {
    if( rv == null) rv = new Point( );
    rv.x = x; // Update its state
    rv.y = y;
    return rv;
    }
    // Create a single point object and reuse it…
    Point p = new Point( );
    for( int i = 0; i < componentArray.length; i++ ) {
    Point position = componentArray[i].getPosition( p );
    // Process position value…
    // Note: Only one Point object is ever created.
    }

    13. J2EE相關

    a)盡量不要將大對象放到HttpSession或其他須序列化的對像中,並註意及時清空Session

    b)使用預編譯語句prepareStatement代替createStatement

    c)盡可能使用連接池

    d)能使用Cache就使用Cache,具體實現可參考jive(CacheCacheableCacheObjectCacheSizesDefaultCacheLinkdListLinkdListNode)或ofbiz(org.ofbiz.core.util. UtilCache.Java)

  • Java基礎:關於Java編程語言中的內部類說明

    提起Java內部類(Inner Class)可能很多人不太熟悉,實際上類似的概念在C++裡也有,那就是嵌套類(Nested Class),關於這兩者的區別與聯繫,在下文中會有對比。內部類從表面上看,就是在類中又定義了一個類(下文會看到,內部類可以在很多地方定義),而實際上並沒有那麼簡單,乍看上去內部類似乎有些多餘,它的用處對於初學者來說可能並不是那麼顯著,但是隨著對它的深入了解,你會發現Java的設計者在內部類身上的確是用心良苦。學會使用內部類,是掌握Java高級編程的一部分,它可以讓你更優雅地設計你的程序結構。下面從以下幾個方面來介紹:

    第一次見面

    public interface Contents {

    int value();

    }

    public interface Destination {

    String readLabel();

    }

    public class Goods {

    private class Content implements Contents {

    private int i = 11;

    public int value() {

    return i;

    }

    }

    protected class GDestination implements Destination {

    private String label;

    private GDestination(String whereTo) {

    label = whereTo;

    }

    public String readLabel() {

    return label;

    }

    }

    public Destination dest(String s) {

    return new GDestination(s);

    }

    public Contents cont() {

    return new Content();

    }

    }

    class TestGoods {

    public static void main(String[] args) {

    Goods p = new Goods();

    Contents c = p.cont();

    Destination d = p.dest(“Beijing”);

    }

    }

    在這個例子裡類Content和GDestination被定義在了類Goods內部,並且分別有著protected和private修飾符來控制訪問級別。 Content代表著Goods的內容,而GDestination代表著Goods的目的地。它們分別實現了兩個接口Content和Destination。在後面的main方法裡,直接用Contents c和Destination d進行操作,你甚至連這兩個內部類的名字都沒有看見!這樣,內部類的第一個好處就體現出來了??隱藏你不想讓別人知道的操作,也即封裝性。

    同時,我們也發現了在外部類作用範圍之外得到內部類對象的第一個方法,那就是利用其外部類的方法創建並返回。上例中的cont()和dest()方法就是這麼做的。那麼還有沒有別的方法呢?當然有,其語法格式如下:

    outerObject=new outerClass(Constructor Parameters);

    outerClass.innerClass innerObject=outerObject.new InnerClass(Constructor Parameters);

    注意在創建非靜態內部類對象時,一定要先創建起相應的外部類對象。至於原因,也就引出了我們下一個話題??非靜態內部類對像有著指向其外部類對象的引用,對剛才的例子稍作修改:

    public class Goods {

    private valueRate=2;

    private class Content implements Contents {

    private int i = 11*valueRate;

    public int value() {

    return i;

    }

    }

    protected class GDestination implements Destination {

    private String label;

    private GDestination(String whereTo) {

    label = whereTo;

    }

    public String readLabel() {

    return label;

    }

    }

    public Destination dest(String s) {

    return new GDestination(s);

    }

    public Contents cont() {

    return new Content();

    }

    }

    修改的部分用藍色顯示了。在這裡我們給Goods類增加了一個private成員變量valueRate,意義是貨物的價值係數,在內部類Content的方法value()計算價值時把它乘上。我們發現,value()可以訪問valueRate,這也是內部類的第二個好處??一個內部類對象可以訪問創建它的外部類對象的內容,甚至包括私有變量!這是一個非常有用的特性,為我們在設計時提供了更多的思路和捷徑。要想實現這個功能,內部類對象就必須有指向外部類對象的引用。 Java編譯器在創建內部類對象時,隱式的把其外部類對象的引用也傳了進去並一直保存著。這樣就使得內部類對象始終可以訪問其外部類對象,同時這也是為什麼在外部類作用範圍之外向要創建內部類對象必須先創建其外部類對象的原因。

    有人會問,如果內部類裡的一個成員變量與外部類的一個成員變量同名,也即外部類的同名成員變量被屏蔽了,怎麼辦?沒事,Java裡用如下格式表達外部類的引用:

    outerClass.this

    有了它,我們就不怕這種屏蔽的情況了。

    靜態內部類

    和普通的類一樣,內部類也可以有靜態的。不過和非靜態內部類相比,區別就在於靜態內部類沒有了指向外部的引用。這實際上和C++中的嵌套類很相像了,Java內部類與C++嵌套類最大的不同就在於是否有指向外部的引用這一點上,當然從設計的角度以及以它一些細節來講還有區別。

    除此之外,在任何非靜態內部類中,都不能有靜態數據,靜態方法或者又一個靜態內部類(內部類的嵌套可以不止一層)。不過靜態內部類中卻可以擁有這一切。這也算是兩者的第二個區別吧。

    局部內部類

    是的,Java內部類也可以是局部的,它可以定義在一個方法甚至一個代碼塊之內。

    public class Goods1 {

    public Destination dest(String s) {

    class GDestination implements Destination {

    private String label;

    private GDestination(String whereTo) {

    label = whereTo;

    }

    public String readLabel() { return label; }

    }

    return new GDestination(s);

    }

    public static void main(String[] args) {

    Goods1 g= new Goods1();

    Destination d = g.dest(“Beijing”);

    }

    }

    上面就是這樣一個例子。在方法dest中我們定義了一個內部類,最後由這個方法返回這個內部類的對象。如果我們在用一個內部類的時候僅需要創建它的一個對象並創給外部,就可以這樣做。當然,定義在方法中的內部類可以使設計多樣化,用途絕不僅僅在這一點。

    下面有一個更怪的例子:

    public class Goods2{

    private void internalTracking(boolean b) {

    if(b) {

    class TrackingSlip {

    private String id;

    TrackingSlip(String s) {

    id = s;

    }

    String getSlip() { return id; }

    }

    TrackingSlip ts = new TrackingSlip(“slip”);

    String s = ts.getSlip();

    }

    }

    public void track() { internalTracking(true); }

    public static void main(String[] args) {

    Goods2 g= new Goods2();

    g.track();

    }

    }

    你不能在if之外創建這個內部類的對象,因為這已經超出了它的作用域。不過在編譯的時候,內部類TrackingSlip和其他類一樣同時被編譯,只不過它由它自己的作用域,超出了這個範圍就無效,除此之外它和其他內部類並沒有區別。

    匿名內部類

    java的匿名內部類的語法規則看上去有些古怪,不過如同匿名數組一樣,當你只需要創建一個類的對象而且用不上它的名字時,使用內部類可以使代碼看上去簡潔清楚。它的語法規則是這樣的:

    new interfacename(){……};或new superclassname(){……};

    下面接著前面繼續舉例子:

    public class Goods3 {

    public Contents cont(){

    return new Contents(){

    private int i = 11;

    public int value() {

    return i;

    }

    };

    }

    }

    這裡方法cont()使用匿名內部類直接返回了一個實現了接口Contents的類的對象,看上去的確十分簡潔。

    在java的事件處理的匿名適配器中,匿名內部類被大量的使用。例如在想關閉窗口時加上這樣一句代碼:

    frame.addWindowListener(new WindowAdapter(){

    public void windowClosing(WindowEvent e){

    System.exit(0);

    }

    });

    有一點需要注意的是,匿名內部類由於沒有名字,所以它沒有構造函數(但是如果這個匿名內部類繼承了一個只含有帶參數構造函數的父類,創建它的時候必須帶上這些參數,並在實現的過程中使用super關鍵字調用相應的內容)。如果你想要初始化它的成員變量,有下面幾種方法:

    如果是在一個方法的匿名內部類,可以利用這個方法傳進你想要的參數,不過記住,這些參數必須被聲明為final。

    將匿名內部類改造成有名字的局部內部類,這樣它就可以擁有構造函數了。

    在這個匿名內部類中使用初始化代碼塊。

    為什麼需要內部類?

    java內部類有什麼好處?為什麼需要內部類?

    首先舉一個簡單的例子,如果你想實現一個接口,但是這個接口中的一個方法和你構想的這個類中的一個方法的名稱,參數相同,你應該怎麼辦?這時候,你可以建一個內部類實現這個接口。由於內部類對外部類的所有內容都是可訪問的,所以這樣做可以完成所有你直接實現這個接口的功能。

    不過你可能要質疑,更改一下方法的不就行了嗎?

    的確,以此作為設計內部類的理由,實在沒有說服力。

    真正的原因是這樣的,java中的內部類和接口加在一起,可以的解決常被C++程序員抱怨java中存在的一個問題??沒有多繼承。實際上,C++的多繼承設計起來很複雜,而java通過內部類加上接口,可以很好的實現多繼承的效果。

  • 新手入門:介紹Java學習的一些主線思路

    Java發展到現在,按應用來分主要分為三大塊:J2SE,J2ME和J2EE。

    這三塊相互補充,應用範圍不同。

    J2SE就是Java2的標準版,主要用於桌面應用軟件的編程;

    J2ME主要應用於嵌入是系統開發,如手機和PDA的編程;

    J2EE是Java2的企業版,主要用於分佈式的網絡程序的開發,如電子商務網站和ERP系統。

    先學習j2se

    要學習j2ee就要先學習j2se,剛開始學習j2se先建議不要使用IDE,然後漸漸的過渡到使用IDE開發,畢竟用它方便嘛。學習j2se推薦兩本書,《java2核心技術一二卷》,《java編程思想》,《java模式》。其中《java編程思想》要研讀,精讀。這一段時間是基本功學習,時間會很長,也可能很短,這要看學習者自身水平而定。

    不要被IDE糾纏

    在學習java和j2ee過程中,你會遇到五花八門的IDE,不要被他們迷惑,學JAVA的時候,要學語言本身的東西,不要太在意IDE的附加功能,JAVA編程在不同IDE之間的轉換是很容易的,過於的在意IDE的功能反而容易耽誤對語言本身的理解。目前流行的IDE有jbuilder,eclipse和eclipse的加強版WSAD。用好其中一個就可以了,推薦從eclipse入手j2ee。因為Jbuilder更適合於寫j2se程序。

    選擇和學習服務器使用配置

    當你有了j2se和IDE的經驗時,可以開始j2ee的學習了,web服務器:tomcat,勿庸置疑,tomcat為學習web服務首選。而應用服務器目前主要有三個:jboss、weblogic、websphere。有很多項目開始採用jboss,並且有大量的公司開始做websphere或weblogic向jboss應用服務器的移植(節省成本),這裡要說的是,學習tomcat和jboss我認為是首選,也是最容易上手的。學習服務器使用配置最好去詢問有經驗的人(有條件的話),因為他們或許一句話就能解決問題,你自己上網摸索可能要一兩天(我就乾過這種傻事),我們應該把主要時間放在學習原理和理論上,一項特定技術的使用永遠代替不了一個人的知識和學問。

    學習web知識

    如果你是在做電子商務網站等時,你可能要充當幾個角色,這是你還要學習:

    html,可能要用到dreamwave等IDE。

    Javascript,學會簡單的數據校驗,數據聯動顯示等等。

    J2eeAPI學習

    學習j2eeAPI和學習服務器應該是一個迭代的過程。

    先學習jsp和servlet編程,這方面的書很多,我建立看oreilly公司的兩本《jsp設計》和《java servlet編程》,oreilly出的書總是那本優秀,不得不佩服。

    學習jdbc數據庫編程,j2ee項目大多都是MIS系統,訪問數據庫是核心。這本應屬於j2se學習中,這裡拿出來強調一下。

    學習jndi api,它和學習ejb可以結合起來。

    學習ejb api,推薦書《精通ejb》

    經過上面的這些的學習,大概可以對付一般的應用了。

    有人說跟著sun公司的《j2ee tutorial》一路學下來,當然也可以。

    學習ejb設計模式和看代碼(最重要)

    設計模式是練內功,其重要性可以這麼說吧,如果你不會用設計模式的話,你將寫出一堆使用了ejb的垃圾,有慢又是一堆bug,其結果不如不用ejb實現( ejb不等於j2ee)

    無論學習什麼語言,都應該看大量代碼,你看的代碼量不到一定數量,是學不好j2ee的。

    目前有很多開源的工程可以作為教材:

    jive論壇

    petstore sun公司

    dune sun公司

    等等,研讀一個,並把它用到自己的工程中來。

    J2ee其他學習

    當你漸漸對j2ee了解到一定深度時,你要開始關注當前領域中的一些技術變化,J2ee是一塊百家爭鳴的領域,大家都在這裡提出自己的解決方案,例如structs,hiberate,ofbiz等等,學習這些東西要你的項目和目標而定,預先補充一下未嘗不可,但不用涉及太深,畢竟學習原理和理論是最最重要的事。

    目前常見j2eeAPI

    JavaServer Pages(JSP)技術1.2

    Java Servlet技術2.3

    JDBC API 2.0

    Java XML處理API(JAXP)1.1

    Enterprise JavaBeans技術2.0

    Java消息服務(JMS)1.0

    Java命名目錄接口(JNDI)1.2

    Java事務API(JTA) 1.0

    JavaMail API 1.2

    JavaBeans激活架構(JAF)1.0

    J2EE連接器體系結構(JCA)1.0

    Java認證和授權服務(JAAS)1.0

    學習上面的某些API要以你的項目而定,了解所有他們總之是有好處的。

    上面印證了大家說的一句話,java語言本身不難學,但是技術太多,所以學java很費勁。回想一下,基本上每個初學者,在剛學習java的時候可能都會問別人這麼一句話,你怎麼知道的哪個方法(api)在哪個包裡的?呵呵,無他,唯手熟爾。

    1基礎是王道。我們的基礎要紮實紮實再紮實。

    以上面的整個流程來看java的技術分支很多,要想完全掌握是絕對不可能的。我們只有從中精通1到2個部分。但是java也是有通性的,所謂萬變不離其宗。 java的所有編程思路都是“面向對象”的編程。所以大家在往更高境界發展以前一定要打好基礎,這樣不管以後是jree還是j3d都有應刃而解的感覺。在這裡強烈推薦“java編程思想”.

    2所謂打好基礎並不是說要熟悉所有的java代碼。我說的意思是要了解java的結構。 class,methode,object,各種套用import,extend讓自己在結構上對java有個立體而且整體的了解即刻。其實java的學習不用固執於對代碼的熟悉,1來java本身帶有很多demo,java2d的所有問題幾乎都有demo的樣例。 2來java是開放代碼,即使沒有demo網絡上也有很多高手把自己的代碼分享。所以不要怕沒有參考,參考是到處都有的。

    3最後還有1點經驗和大家分享,對sun的api一定要學會活用,不論是學習還是作為參考api都有很大的幫助,在完全了解java的結構的基礎上,不論什麼方法都是可以通過api來找到的.所以不要怕找不到方法,了解結構,了解api就能找到方法。

  • 台北舉行“JAVA認證日”會場報名考試優惠了

    目前JAVA認證考試卷的價格是6600,會場當天購買優惠價是5300,詳細可參考一下活動網頁的訊息。

    時間:2009年7月31日

    地點:台北國際會議中心
    活動網址:http://weekly.ithome.com.tw/seminar/jcd2009/

    引用網址:http://itking-sunny.blogspot.com/2009/06/2009-java.html

    P.S. 上次一個朋友跟我說SCJP已經漲到300美金,我很納悶地去Prometric網站查,果然查到是300美金。不過當我看到JAVA認證日的活動訊息時我才想起,多數人考JAVA都是先去跟恆毅等SUN原廠授權中心買認證試卷而非在Prometric線上刷卡,而買認證試卷的金額目前訂價是台幣6600而非300美金,若在7/31的JAVA認證日購買就是優惠價3500。

    這個資訊給近期半年內有要考JAVA認證的朋友,若確定要參加考試先去買來放著可以便宜些。

  • Java入門需掌握的30個基本概念

    Java的白皮書為我們提出了Java語言的11個關鍵特性。

    (1)Easy:Java的語法比C++的相對簡單,另一個方面就是Java能使軟件在很小的機器上運行,基礎解釋其和類庫的支持的大小約為40kb,增

    加基本的標準庫和線程支持的內存需要增加125kb。
    (2)分佈式:Java帶有很強大的TCP/IP協議族的例程庫,Java應用程序能夠通過URL來穿過網絡來訪問遠程對象,由於servlet機制的出現,使

    Java編程非常的高效,現在許多的大的web server都支持servlet。
    (3)OO:面向對象設計是把重點放在對象及對象的接口上的一個編程技術.其面向對象和C++有很多不同,在與多重繼承的處理及Java的原類模

    型。
    (4)健壯特性:Java採取了一個安全指針模型,能減小重寫內存和數據崩潰的可能型。
    (5)安全:Java用來設計網路和分佈系統,這帶來了新的安全問題,Java可以用來構建防病毒和防攻擊的System.事實證明Java在防毒這一方

    面做的比較好。
    (6)中立體系結構:Java編譯其生成體系結構中立的目標文件格式可以在很多處理器上執行,編譯器產生的指令字節碼(Javabytecode)實現此

    特性,此字節碼可以在任何機器上解釋執行。
    (7)可移植性:Java中對基本數據結構類型的大小和算法都有嚴格的規定所以可移植性很好。
    (8)多線程:Java處理多線程的過程很簡單,Java把多線程實現交給底下操作系統或線程程序完成.所以多線程是Java作為服務器端開發語言

    的流行原因之一。
    (9)Applet和servlet:能夠在網頁上執行的程序叫Applet,需要支持Java的瀏覽器很多,而applet支持動態的網頁,這是很多其他語言所不

    能做到的。
    基本概念?
    1.OOP中唯一關係的是對象的接口是什麼,就像計算機的銷售商她不管電源內部結構是怎樣的,他只關係能否給你提供電就行了,也就是只

    要知道can or not而不是how and why.所有的程序是由一定的屬性和行為對象組成的,不同的對象的訪問通過函數調用來完成,對象間所有

    的交流都是通過方法調用,通過對封裝對像數據,很大限度上提高複用率。
    2.OOP中最重要的思想是類,類是模板是藍圖,從類中構造一個對象,即創建了這個類的一個實例(instance)。
    3.封裝:就是把數據和行為結合起在一個包中)並對對象使用者隱藏數據的實現過程,一個對像中的數據叫他的實例字段(instance field)。
    4.通過擴展一個類來獲得一個新類叫繼承(inheritance),而所有的類都是由Object根超類擴展而得,根超類下文會做介紹。
    5.對象的3個主要特性
    behavior—說明這個對象能做什麼.
    state—當對象施加方法時對象的反映.
    identity—與其他相似行為對象的區分標誌.
    每個對像有唯一的indentity而這3者之間相互影響.

    6.類之間的關係:
    use-a :依賴關係
    has-a :聚合關係
    is-a :繼承關係–例:A類繼承了B類,此時A類不僅有了B類的方法,還有其自己的方法.(個性存在於共性中)
    7.構造對象使用構造器:構造器的提出,構造器是一種特殊的方法,構造對象並對其初始化。
    例:Data類的構造器叫Data
    new Data()—構造一個新對象,且初始化當前時間.
    Data happyday=new Data()—把一個對象賦值給一個變量happyday,從而使該對象能夠多次使用,此處要聲明的使變量與對像變量二者是

    不同的.new返回的值是一個引用。
    構造器特點:構造器可以有0個,一個或多個參數
    構造器和類有相同的名字
    一個類可以有多個構造器
    構造器沒有返回值
    構造器總是和new運算符一起使用.

    8.重載:當多個方法具有相同的名字而含有不同的參數時,便發生重載.編譯器必須挑選出調用哪個方法。
    9.包(package)Java允許把一個或多個類收集在一起成為一組,稱作包,以便於組織任務,標準Java庫分為許多包.java.lang java.util

    java,net等,包是分層次的所有的java包都在java和javax包層次內。
    10.繼承思想:允許在已經存在的類的基礎上構建新的類,當你繼承一個已經存在的類時,那麼你就復用了這個類的方法和字段,同時你可以

    在新類中添加新的方法和字段。
    11.擴展類:擴展類充分體現了is-a的繼承關係.形式為:class (子類) extends (基類)。
    12.多態:在java中,對像變量是多態的.而java中不支持多重繼承。
    13.動態綁定:調用對象方法的機制。
    (1)編譯器檢查對象聲明的類型和方法名。
    (2)編譯器檢查方法調用的參數類型。
    (3)靜態綁定:若方法類型為priavte static final編譯器會準確知道該調用哪個方法。
    (4)當程序運行並且使用動態綁定來調用一個方法時,那麼虛擬機必須調用x所指向的對象的實際類型相匹配的方法版本。
    (5)動態綁定:是很重要的特性,它能使程序變得可擴展而不需要重編譯已存代碼。
    14.final類:為防止他人從你的類上派生新類,此類是不可擴展的。
    15.動態調用比靜態調用花費的時間要長。
    16.抽像類:規定一個或多個抽象方法的類本身必須定義為abstract。
    例: public abstract string getDescripition
    17.Java中的每一個類都是從Object類擴展而來的。
    18.object類中的equal和toString方法。
    equal用於測試一個對像是否同另一個對象相等。
    toString返回一個代表該對象的字符串,幾乎每一個類都會重載該方法,以便返回當前狀態的正確表示.
    (toString方法是一個很重要的方法)
    19.通用編程:任何類類型的所有值都可以同object類性的變量來代替。
    20.數組列表:ArrayList動態數組列表,是一個類庫,定義在java.uitl包中,可自動調節數組的大小。
    21.class類object類中的getclass方法返回ckass類型的一個實例,程序啟動時包含在main方法的類會被加載,虛擬機要加載他需要的所有

    類,每一個加載的類都要加載它需要的類。
    22.class類為編寫可動態操縱java代碼的程序提供了強大的功能反射,這項功能為JavaBeans特別有用,使用反射Java能支持VB程序員習慣

    使用的工具。
    能夠分析類能力的程序叫反射器,Java中提供此功能的包叫Java.lang.reflect反射機制十分強大.
    1.在運行時分析類的能力。
    2.在運行時探察類的對象。
    3.實現通用數組操縱代碼。
    4.提供方法對象。

    而此機制主要針對是工具者而不是應用及程序。
    反射機制中的最重要的部分是允許你檢查類的結構.用到的API有:
    java.lang.reflect.Field返回字段.
    java.reflect.Method返回方法.
    java.lang.reflect.Constructor返回參數.
    方法指針:java沒有方法指針,把一個方法的地址傳給另一個方法,可以在後面調用它,而接口是更好的解決方案。
    23.接口(Interface)說明類該做什麼而不指定如何去做,一個類可以實現一個或多個interface。
    24.接口不是一個類,而是對符合接口要求的類的一套規範。
    若實現一個接口需要2個步驟:
    1.聲明類需要實現的指定接口。
    2.提供接口中的所有方法的定義。
    聲明一個類實現一個接口需要使用implements關鍵字
    class actionB implements Comparable其actionb需要提供CompareTo方法,接口不是類,不能用new實例化一個接口.
    25.一個類只有一個超類,但一個類能實現多個接口。 Java中的一個重要接口:Cloneable sc-
    26.接口和回調.編程一個常用的模式是回調模式,在這種模式中你可以指定當一個特定時間發生時回調對像上的方法。
    例:ActionListener接口監聽. 
    類似的API有:java.swing.JOptionPane
    java.swing.Timer
    java.awt.Tookit
    27.對象clone:clone方法是object一個保護方法,這意味著你的代碼不能簡單的調用它。
    28.內部類:一個內部類的定義是定義在另一個內部的類。
    原因是:
    1.一個內部類的對象能夠訪問創建它的對象的實現,包括私有數據。
    2.對於同一個包中的其他類來說,內部類能夠隱藏起來。
    3.匿名內部類可以很方便的定義回調。
    4.使用內部類可以非常方便的編寫事件驅動程序。
    29.代理類(proxy):
    1.指定接口要求所有代碼
    2.object類定義的所有的方法(toString equals)
    30.數據類型:Java是強調類型的語言,每個變量都必須先申明它都類型,java中總共有8個基本類型.4種是整型,2種是浮點型,一種是字符型,被用於Unicode編碼中的字符,布爾型

  • Java基礎知識J2EE初學者需要注意的問題

    J2EE體系結構簡單介紹

    一、J2EE提出的背景

    1、企業級應用框架的需求

    在許多企業級應用中,例如數據庫連接、郵件服務、事務處理等都是一些通用企業需求模塊,這些模塊如果每次再開發中都由開發人員來完

    成的話,將會造成開發週期長和代碼可靠性差等問題。於是許多大公司開發了自己的通用模塊服務。這些服務性的軟件系列同陳為中間件。

    2、為了通用必須要提出規範,不然無法達到通用

    在上面的需求基礎之上,許多公司都開發了自己的中間件,但其與用戶的溝通都各有不同,從而導致用戶無法將各個公司不同的中間件組裝

    在一塊為自己服務。從而產生瓶頸。於是提出標準的概念。其實J2EE就是基於JAVA技術的一系列標準。

    注:中間件的解釋中間件處在操作系統和更高一級應用程序之間。他充當的功能是:將應用程序運行環境與操作系統隔離,從而實現應用程

    序開發者不必為更多系統問題憂慮,而直接關注該應用程序在解決問題上的能力。我們後面說到的容器的概念就是中間件的一種。

    二、相關名詞解釋

    容器:充當中間件的角色

    WEB容器:給處於其中的應用程序組件(JSP,SERVLET)提供一個環境,使JSP,SERVLET直接更容器中的環境變量接口交互,不必關注其它系

    統問題。主要有WEB服務器來實現。例如:TOMCAT,WEBLOGIC,WEBSPHERE等。該容器提供的接口嚴格遵守J2EE規範中的WEB APPLICATION標準

    。我們把遵守以上標準的WEB服務器就叫做J2EE中的WEB容器。

    EJB容器:Enterprise java bean容器。更具有行業領域特色。他提供給運行在其中的組件EJB各種管理功能。只要滿足J2EE規範的EJB放入

    該容器,馬上就會被容器進行高效率的管理。並且可以通過現成的接口來獲得系統級別的服務。例如郵件服務、事務管理。

    WEB容器和EJB容器在原理上是大體相同的,更多的區別是被隔離的外界環境。 WEB容器更多的是跟基於HTTP的請求打交道。而EJB容器不是

    。它是更多的跟數據庫、其它服務打交道。但他們都是把與外界的交互實現從而減輕應用程序的負擔。例如SERVLET不用關心HTTP的細節,

    直接引用環境變量session,request,response就行、EJB不用關心數據庫連接速度、各種事務控制,直接由容器來完成。

    RMI/IIOP:遠程方法調用/internet對象請求中介協議,他們主要用於通過遠程調用服務。例如,遠程有一台計算機上運行一個程序,它提供

    股票分析服務,我們可以在本地計算機上實現對其直接調用。當然這是要通過一定的規範才能在異構的系統之間進行通信。 RMI是JAVA特有

    的。

    JNDI:JAVA命名目錄服務。主要提供的功能是:提供一個目錄系統,讓其它各地的應用程序在其上面留下自己的索引,從而滿足快速查找和

    定位分佈式應用程序的功能。

    JMS:JAVA消息服務。主要實現各個應用程序之間的通訊。包括點對點和廣播。

    JAVAMAIL:JAVA郵件服務。提供郵件的存儲、傳輸功能。他是JAVA編程中實現郵件功能的核心。相當MS中的EXCHANGE開發包。

    JTA:JAVA事務服務。提供各種分佈式事務服務。應用程序只需調用其提供的接口即可。

    JAF:JAVA安全認證框架。提供一些安全控制方面的框架。讓開發者通過各種部署和自定義實現自己的個性安全控制策略。

    EAI:企業應用集成。是一種概念,從而牽涉到好多技術。 J2EE技術是一種很好的集成實現。

    三、J2EE的優越性

    1、基於JAVA技術,平台無關性表現突出

    2、開放的標準,許多大型公司已經實現了對該規範支持的應用服務器。如BEA ,IBM,ORACLE等。

    3、提供相當專業的通用軟件服務。

    4、提供了一個優秀的企業級應用程序框架,對快速高質量開發打下基礎

    四、現狀

    J2EE是由SUN公司開發的一套企業級應用規範。現在最高版本是1.4。支持J2EE的應用服務器有IBM WEBSPHERE APPLICATION SERVER,BEA

    WEBLOGIC SERVER,JBOSS,ORACLE APPLICATION SERVER,SUN ONE APPLICATION SERVER等。