1. 程式人生 > >Java與C 開發上的一些差異與轉換方法

Java與C 開發上的一些差異與轉換方法

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow

也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!

                此文尚未寫完,有時間逐漸補全。

Java和C#訪問修飾符的差異性與轉換:


在C#中,我們通常會使用到如下幾種訪問修飾符:

public 訪問不受限制。

protected 訪問僅限於包含類或從包含類派生的型別。

internal 訪問僅限於當前程式集。

protected internal 訪問僅限於當前程式集或從包含類派生的型別。

private 訪問僅限於包含型別。


而在Java裡,則僅有以下幾種可供調配:

public  同C#一致

protected 同C#一致

private 同C#一致


internal 在Java中無等價存在(在Java中,如果不為函式或類增加任何修飾符,則意味著僅限當前包中所有類訪問,同internal作用有近似處,但範圍沒有internal大。而在C#中,不用任何範圍修飾符時,預設的則是protected,不能在類外被訪問)

另外C#的Type,基本等價於Java的Class,小弟在LGame的C#版中也提供有一些轉化工具(此類工具都在名稱空間Org.Loon.Framework.Xna.Java下)。

Java和C#中this關鍵字的差異性與轉換:


Java同C#的this關鍵字基礎作用一致,都是引用當前類的當前例項,但細節使用處有些差異。

比如在Java中,我們想利用this呼叫一個已有的建構函式,使用樣式如下:

public test{
   this(0,0);
}

public test(int x,int y){

}


而在C#裡,則需要如下的使用方式:

public test : this(0,0){

}

public test(int x,int y){

}


而從派生類中訪問基類的成員,也就是呼叫父類的方法,則有如下分別。

Java中

public test(){
   super(0,0);
}

C#中

public test():base(0,0){

}


Java和C#陣列的差異性與轉換:


Java與C#陣列的差異,主要體現在多維陣列的定義方式上(一維毫無差異)。

比如我們在Java中定義一個3x3的二維陣列,需要如下設定。

int[][] test = new int[3][3];


讀取方式則為如下:

int v = test[0][0]


而同樣的設定,C#中則必須寫成

int[,] test = new int[3,3];


讀取方式就要順應格式,變成這樣(附帶一提,小弟在LGame的C#版裡提供有仿寫Java陣列的方式):

int v = test[0,0];


另外,C#陣列設定上比較嚴謹,沒有Java那麼隨意。

比如Java中構建如下樣式陣列,不會有任何問題:

String test[] = new String[3];


而在C#中則必須為如下樣式:

string[] test = new string[3];


假如將[]寫在變數名而非變數型別後,C#是不認的,連編譯都過不去。

Java和C#函式差異性與轉換:


在Java中使用函式,不宣告[不可重寫],就可以直接[重寫]。

在Java環境中,如果我們需要一個公有方法不能重寫,需要宣告這個函式為final(基本等價於C#的sealed修飾符,但sealed僅對類有效)。

假設A類有公有函式:

public void test(){}

則B類無需任何修飾,複寫一次該函式,重寫就會被完成。

public void test(){}

如果我們不希望A類中函式test被重置,則需要特別修飾test函式,比如下例:

public final void test(){}


而在C#函式中,特性與Java正好相反,不宣告函式[可以重寫],意味著對應一定[無法重寫]。

在C#中,假設也有A類,想要完成如Java般操作,則必須先作如下設定:

public virtual void test(){}

而後需要重寫的B類,再做如下修飾,才能完整重寫過程(在C#裡,假如我們需要一個公有方法可以重寫,則必須宣告為override。Java雖然有override的元資料註釋,但可有可無……)。

public override void test(){}

而C#中不希望test被重置,則無需任何設定,直接如下即可:

public void test(){}


另外,virtual修飾符不能與 static、abstract, private或者 override修飾符同時使用(否則VS直接編譯失敗,根本無法走到執行)。

Java和C#全域性常量差異性與轉換:

有時我們需要一個數值永遠固定為單一量,這是我們就需要一個全域性常量。

在C#中,這點延續了標準C語系的做法,直接使用const關鍵字即可(不需要static描述,有此關鍵字就是全域性使用),比如:

public const int type = 0;

這樣,我們直接使用類名.type的方式,就可以在任何場合訪問到這個常量值。

而在Java中使用,實現同樣效果則比較麻煩,因為Java雖然有const關鍵字,卻是保留值(只佔位,無實際功能),而需要由final與static關鍵字結合使用,方可達到近似效果。比如:

public final static int type = 0;


這樣,我們使用Java類名.type的方式,才可以在任何場合都訪問到這個常量值。

另外在C#中,也可以使用下列方式來達到目的:

public readonly static int type = 0 ;


其實從本質上講,上述C#表述才和Java的常量用法更貼近(const欄位是編譯時常量,而readonly欄位可用於執行時常量,意味著初始化時有一次動態賦值的機會)。

Java和C#繼承的差異性與轉換:


在名稱上,C#與Java相同,都是類為class(但獲得當前類的class時,卻不能如Java般getClass,而要GetType) , 介面為interface,抽象為abstract。

但Java繼承類需要修飾符【extends】,實現介面需要修飾符【implements】。

比如:

public class Test extends A implements  B {

}


而C#僅需一個【:】搞定。

public class Test : A , B {

}


編譯時系統會分清那個是繼承,那個是介面或其他型別(struct啥的不能被繼承)。

另外,想要阻止某個類被派生時,Java中可以使用final關鍵字,C#中可以使用sealed關鍵詞來修飾目標類。

不過C#中也有一個不如Java的特性,讓小弟非常彆扭,那就是interface中不能存在常量(不能包含域(Field),且函式前也不能存在public關鍵字),導致將Java的某些程式碼移向C#只能微調。

Java和C#屬性的差異性與轉換:


在Java中定義和訪問屬性,在規範上要用get和set方法(當然,不照規矩走也沒人攔著),可以不成對出現。

比如


      private String name;

        public void setName(string n){
           this.name = n;
    }

    public string getName(){
           return this.name;
    }


而在C#中,則可以直接用如下方式來訪問name。

        public string name
        {
            set;
            get;
        }


此外,Java中我們也可以直接將name設定為public的,這樣表面功能上同上述C#語法彷彿沒有區別。但是,在C#中我們卻可以自由限制該方法的set和get屬性,以調控究竟暴露給使用者怎樣的操作許可權,要比Java中批量生成海量Set與Get方便一些。

附帶一提,如果我們呼叫C#的Type中GetMethods方法遍歷函式,可以看見name將變成如下樣式。

set_name

get_name


其實C#就是替我們自動新增好了set與get屬性,與Java在執行機制上倒沒有本質區別。


Java和C#在多執行緒管理上的差異性與轉換:

C#中使用MethodImplOptions.Synchronized進行執行緒同步

[MethodImpl(MethodImplOptions.Synchronized)]
public void test(){

}


大體等於Java中

public synchronized void test(){

}

C#中使用lock關鍵字作為互斥鎖

object o = new object();

public void test(){
   lock(o){
   
   }
}


大體等於Java中

Object o = new Object();

public void test(){
   synchronized(o){
   
   }
}


C#中使用Monitor.Enter作為排他鎖

List<object> list = new List<object>();

public void test()
{
    Monitor.Enter(list);
    //具體的list排它操作
    //......
    Monitor.Exit(list);
}

在Java中沒有等價存在,不過有一些功能近似類在java.util.concurrent.locks包下可供調配,比如寫成這樣:

    ReentrantReadWriteLock ilock = new ReentrantReadWriteLock();

    Lock readLock = ilock.readLock();

    Lock writeLock = ilock.writeLock();

    List<Object> list = new ArrayList<Object>();

    public void test() {
        try {
            // 讀取鎖定
            readLock.lock();
            // 寫入解鎖
            writeLock.unlock();
            // 具體的list排它操作
            // ......
        } finally {
            // 讀取解鎖
            readLock.unlock();
            // 寫入鎖定
            writeLock.lock();
        }
    }


其它C#多執行緒常用函式與Java間函式的關係,可參見如下實現(也可參考LGame的C#版JavaRuntime類中):

        public static void Wait(object o)
        {
            Monitor.Wait(o);
        }

        public static void Wait(object o, long milis)
        {
            Monitor.Wait(o, (int)milis);
        }

        public static void Wait(object o, TimeSpan t)
        {
            Monitor.Wait(o, t);
        }

        public static void NotifyAll(object o)
        {
            Monitor.PulseAll(o);
        }

        public static void Notify(object o)
        {
            Monitor.Pulse(o);
        }



           

給我老師的人工智慧教程打call!http://blog.csdn.net/jiangjunshow

這裡寫圖片描述