C#跟JAVA使用上的差異

Java當初的設計理念是簡單、安全
也因此可以很快上手,但也因此少掉很多在C++中好用以及麻煩的東西

以下是我從C#轉學JAVA的心得

Java SE6技術手冊,我一個禮拜就看完了
這是一本很好的上手書
實際上也只有半本(CH13前)的部分屬於必需看過的部分
剩下的Stream、Thread、Reflection、Annotation,等要用到時再去查
如果打算走Android,Reflection那部分最好稍微看過
Android常常用Reflection去調用apk裡的東西

但也建議你留一本Thinking in JAVA在身邊
Thinking in JAVA講的比較深,有時候遇到一些問題
去找Thinking in JAVA比較能獲得清楚的解答

C#的概念是模仿Java,但寫起來比較像C++
像指標、函數指標、多載運算子、goto等東西,C#有保留下來
但在Java中全部都被沒收了
少了那些複雜的東西,所以能學的很快

C#的關鍵字比Java多很多
相較之下Java簡單輕快,只要知道那些缺少的東西要怎麼去轉換
就能寫得很順

在基礎語法方面

        goto XXX;
        XXX:

這種東西在Java中被

        break XXX;
        continum XXX;

取代

例如:

        XXX:
        {
           break XXX;
        }

而且只能往後跳,不能往前跳
如果要往前,只能用while等迴圈去控制程式流程

foreach 在Java中的型式是
for (iterable_type iterable_element : iterable)

修飾詞 (private、public、protected)
在C#中只有三種,如果沒加,就會變成private
在Java中如果不加修飾詞,代表的是同一套件內的成員都能使用他

Java跟C#的類別配置不太一樣
C#用namespace去區別class的「域」
而檔案跟程式碼沒直接關係

但Java是用套件區分,而且一個.java檔案只能放一個public class
且檔案名稱需與類別名稱同名
不像C#愛放哪裡就放哪裡,嫌class太大還能用partial class拆成兩三個檔案

還有, C#可以為現成的class亂加方法進去,例如:

    static class Util
    {
        public static int Square (this int i ){return i*i};
    }
    int x = 100;
    x = x.Square(); //x == 10000

java沒這種東西,如果想擴充,只能繼承它
不過,C#中因為有struct才比較需要這樣做
但Java中都是物件,就不需要

覆寫(Override)
在C#中要宣告override才准繼承的成員去覆寫
但是Java中只要直接覆寫即可
Method前面的 @Override 只是給編譯器看的,不加也沒事

多載運算子
C#可以為自定的類別宣告轉型運算子、算術運算子
但在Java中…. 沒辦法,請把這個功能忘了
只能寫個Method去轉型、去相加、去相減

指標
在C#中的ref、out是在Method中用來取代指標的功能
在Java中也沒有
不過,我看過個寫法是,把變數放進陣列,把陣列傳進Method
硬是把算完的東西用陣列帶出來

Java容器物件都在java.util底下
跟C#差異不會很大,只是名稱不一樣
若要說比較大的差異……
像是C#中是用 List,但是在Java裡面只能用List
而且會經過boxing、unboxing

在名稱方面,在C#中允許

        interface A{}
        class A{}

這種同名泛型,但是在Java中不允許
以及,在C#中遇到必須同時繼承兩個介面時
例如:

        interface A{void A();}
        interface B{int A();}

在C#中可以用

        void A.A(){}
        int B.A(){return 0;}

的方式去區別兩個函式是繼承自哪個介面
Java沒這種東西,理由是:基於Java的特性,根本不需要
當初也覺得撞名很嚴重,但在Java有自己的解決辦法
這等一下講

C#有delegate、event這種類似函數指標的東西
在Java中沒有
C#中常常經過委派去設定按鍵、鍵盤事件
在Java中是用另一方式
這也等一下講

要說Java中比較特別的東西
就是Inner class
C#雖然也有,但C#的Inner class就沒有像Java中的那樣好用
C#比較像是「把一個class放進一個跟上層class同名的namespace裡面」
上層class跟Inner class沒有直接關係
感覺很雞肋,我寫C#時幾乎沒用過
除非是用static class來紀錄一些全域變數 (有分層比較不會搞混)

但Java中,Inner class卻像是「上層class 的一部份」
他本身會隱含上層class的參照
這特性被用來處理很多事

舉例來說:

    class A
    {
       void A(){}
       class B
       {
           void Method1()
           {
               A(); //在C#中不會過,但Java中可以
           }
       }
    }

也因為如此,在java中常常這樣用

    class A
    {
       class B implements View.OnClickListener()
       {
          @Override
          public void onClick(View v)
          {
          }
       }
       class C implements Button.OnClickListener()
       {
          @Override
          public void onClick(View v)
          {
          }
       }
    }

這樣一來,就能避免interface中的Method撞名的問題
而且onClick裡面的程式碼也可以自由使用class A裡的欄位、Method

以及,之前在C#中常常用委派(delegate)設定一些點擊、按鍵等callback事件
那時是直接塞方法名稱就可以,例如:

   class C
   {
      public void onClickEevent()
      {
         //點下Button時要做的事
      }
   }

設定時:

Button.OnClick = onClickEevent;

但在Java中的做法是這樣:

   class C
   {
       class OnClickEvent implements Button.OnClickListener()
       {
          @Override
          public void onClick(View v)
          {
              //點下Button時要做的事
          }
       }
   }

設定時:

    Button.setOnClickListener(new OnClickEvent());

其他Java的SDK我不知道是怎麼設計
但是在Android SDK裡,設定某個條件觸發某個狀況,都是這樣寫

除非打算深入研究Java
否則,在使用上,Java真的簡潔成這個樣子
Java寫起來一點也不花俏,不用去記一些奇奇怪怪的寫法
用最單純的寫法就對了

如果覺得寫起來很卡、力不從心
那就去找找網路
大概看一陣子範例,就知道Java style的寫法是怎麼樣

中文java doc文件在這裡 http://nothing.tw/JDK_API_1_6/

1 Comment
  1. NeiL 說道:

    C#的概念是模仿Java? C#大概只有在.NET 1.1以前才有模仿, 之後2.0 java還抄c#的metadata… 之後c#的語言特性就已超過java. c#有擴充函式可以做mixin,因而發展出linq,再之後又有dynamic object和TPL。 delegate和匿名函式是c#的最小執行單位, 用起來很像函式指標,但只是很像因為它是managed. java只支援匿名物件, 不支援匿名函式, 所以都需要用物件包起來. java一度發展落後,好在被收購後才開始有進展. 以高階語言來說, java太落後了.

Comments are closed.

Welcome , today is 星期二, 2017/11/21