此文尚未寫完,有時(shí)間逐漸補(bǔ)全。
Java和C#訪問修飾符的差異性與轉(zhuǎn)換:
在C#中,我們通常會(huì)使用到如下幾種訪問修飾符:
public 訪問不受限制。
protected 訪問僅限于包含類或從包含類派生的類型。
internal 訪問僅限于當(dāng)前程序集。
protected internal 訪問僅限于當(dāng)前程序集或從包含類派生的類型。
private 訪問僅限于包含類型。
而在Java里,則僅有以下幾種可供調(diào)配:
public 同C#一致
protected 同C#一致
private 同C#一致
internal 在Java中無等價(jià)存在(在Java中,如果不為函數(shù)或類增加任何修飾符,則意味著僅限當(dāng)前包中所有類訪問,同internal作用有近似處,但范圍沒有 internal大。而在C#中,不用任何范圍修飾符時(shí),默認(rèn)的則是protected,不能在類外被訪問)
另外C#的Type,基本等價(jià)于Java的Class,小弟在LGame的C#版中也提供有一些轉(zhuǎn)化工具(此類工具都在命名空間Org.Loon.Framework.Xna.Java下)。
Java和C#中this關(guān)鍵字的差異性與轉(zhuǎn)換:
Java同C#的this關(guān)鍵字基礎(chǔ)作用一致,都是引用當(dāng)前類的當(dāng)前實(shí)例,但細(xì)節(jié)使用處有些差異。
比如在Java中,我們想利用this調(diào)用一個(gè)已有的構(gòu)造函數(shù),使用樣式如下:
public test{
this(0,0);
}
public test(int x,int y){
}
而在C#里,則需要如下的使用方式:
public test : this(0,0){
}
public test(int x,int y){
}
而從派生類中訪問基類的成員,也就是調(diào)用父類的方法,則有如下分別。
Java中
public test(){
super(0,0);
}
C#中
public test():base(0,0){
}
Java和C#數(shù)組的差異性與轉(zhuǎn)換:
Java與C#數(shù)組的差異,主要體現(xiàn)在多維數(shù)組的定義方式上(一維毫無差異)。
比如我們?cè)贘ava中定義一個(gè)3x3的二維數(shù)組,需要如下設(shè)定。
int[][] test = new int[3][3];
讀取方式則為如下:
int v = test[0][0]
而同樣的設(shè)定,C#中則必須寫成
int[,] test = new int[3,3];
讀取方式就要順應(yīng)格式,變成這樣(附帶一提,小弟在LGame的C#版里提供有仿寫Java數(shù)組的方式):
int v = test[0,0];
另外,C#數(shù)組設(shè)定上比較嚴(yán)謹(jǐn),沒有Java那么隨意。
比如Java中構(gòu)建如下樣式數(shù)組,不會(huì)有任何問題:
String test[] = new String[3];
而在C#中則必須為如下樣式:
string[] test = new string[3];
假如將[]寫在變量名而非變量類型后,C#是不認(rèn)的,連編譯都過不去。
Java和C#函數(shù)差異性與轉(zhuǎn)換:
在Java中使用函數(shù),不聲明[不可重寫],就可以直接[重寫]。
在Java環(huán)境中,如果我們需要一個(gè)公有方法不能重寫,需要聲明這個(gè)函數(shù)為final(基本等價(jià)于C#的sealed修飾符,但sealed僅對(duì)類有效)。
假設(shè)A類有公有函數(shù):
public void test(){}
則B類無需任何修飾,復(fù)寫一次該函數(shù),重寫就會(huì)被完成。
public void test(){}
如果我們不希望A類中函數(shù)test被重置,則需要特別修飾test函數(shù),比如下例:
public final void test(){}
而在C#函數(shù)中,特性與Java正好相反,不聲明函數(shù)[可以重寫],意味著對(duì)應(yīng)一定[無法重寫]。
在C#中,假設(shè)也有A類,想要完成如Java般操作,則必須先作如下設(shè)定:
public virtual void test(){}
而后需要重寫的B類,再做如下修飾,才能完整重寫過程(在C#里,假如我們需要一個(gè)公有方法可以重寫,則必須聲明為override。Java雖然有override的元數(shù)據(jù)注釋,但可有可無……)。
public override void test(){}
而C#中不希望test被重置,則無需任何設(shè)定,直接如下即可:
public void test(){}
另外,virtual修飾符不能與static、abstract, private或者override修飾符同時(shí)使用(否則VS直接編譯失敗,根本無法走到運(yùn)行)。
Java和C#全局常量差異性與轉(zhuǎn)換:
有時(shí)我們需要一個(gè)數(shù)值永遠(yuǎn)固定為單一量,這是我們就需要一個(gè)全局常量。
在C#中,這點(diǎn)延續(xù)了標(biāo)準(zhǔn)C語系的做法,直接使用const關(guān)鍵字即可(不需要static描述,有此關(guān)鍵字就是全局使用),比如:
public const int type = 0;
這樣,我們直接使用類名.type的方式,就可以在任何場(chǎng)合訪問到這個(gè)常量值。
而在Java中使用,實(shí)現(xiàn)同樣效果則比較麻煩,因?yàn)镴ava雖然有const關(guān)鍵字,卻是保留值(只占位,無實(shí)際功能),而需要由final與static關(guān)鍵字結(jié)合使用,方可達(dá)到近似效果。比如:
public final static int type = 0;
這樣,我們使用Java類名.type的方式,才可以在任何場(chǎng)合都訪問到這個(gè)常量值。
另外在C#中,也可以使用下列方式來達(dá)到目的:
public readonly static int type = 0 ;
其實(shí)從本質(zhì)上講,上述C#表述才和Java的常量用法更貼近(const字段是編譯時(shí)常量,而readonly字段可用于運(yùn)行時(shí)常量,意味著初始化時(shí)有一次動(dòng)態(tài)賦值的機(jī)會(huì))。
Java和C#繼承的差異性與轉(zhuǎn)換:
在名稱上,C#與Java相同,都是類為class(但獲得當(dāng)前類的class時(shí),卻不能如Java般getClass,而要GetType) , 接口為interface,抽象為abstract。
但Java繼承類需要修飾符【extends】,實(shí)現(xiàn)接口需要修飾符【implements】。
比如:
public class Test extends A implements B {
}
而C#僅需一個(gè)【:】搞定。
public class Test : A , B {
}
編譯時(shí)系統(tǒng)會(huì)分清那個(gè)是繼承,那個(gè)是接口或其他類型(struct啥的不能被繼承)。
另外,想要阻止某個(gè)類被派生時(shí),Java中可以使用final關(guān)鍵字,C#中可以使用sealed關(guān)鍵詞來修飾目標(biāo)類。
不過C#中也有一個(gè)不如Java的特性,讓小弟非常別扭,那就是interface中不能存在常量(不能包含域(Field),且函數(shù)前也不能存在public關(guān)鍵字),導(dǎo)致將Java的某些代碼移向C#只能微調(diào)。
Java和C#屬性的差異性與轉(zhuǎn)換:
在Java中定義和訪問屬性,在規(guī)范上要用get和set方法(當(dāng)然,不照規(guī)矩走也沒人攔著),可以不成對(duì)出現(xiàn)。
比如
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設(shè)定為public的,這樣表面功能上同上述C#語法仿佛沒有區(qū)別。但是,在C#中我們卻可以自由限制該方法的set和get屬性,以調(diào)控究竟暴露給用戶怎樣的操作權(quán)限,要比Java中批量生成海量Set與Get方便一些。
附帶一提,如果我們調(diào)用C#的Type中GetMethods方法遍歷函數(shù),可以看見name將變成如下樣式。
set_name
get_name
其實(shí)C#就是替我們自動(dòng)添加好了set與get屬性,與Java在運(yùn)行機(jī)制上倒沒有本質(zhì)區(qū)別。
Java和C#在多線程管理上的差異性與轉(zhuǎn)換:
C#中使用MethodImplOptions.Synchronized進(jìn)行線程同步
[MethodImpl(MethodImplOptions.Synchronized)]
public void test(){
}
大體等于Java中
public synchronized void test(){
}
C#中使用lock關(guān)鍵字作為互斥鎖
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中沒有等價(jià)存在,不過有一些功能近似類在java.util.concurrent.locks包下可供調(diào)配,比如寫成這樣:
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#多線程常用函數(shù)與Java間函數(shù)的關(guān)系,可參見如下實(shí)現(xiàn)(也可參考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);
}
浙公網(wǎng)安備 33010602011771號(hào)