zoukankan      html  css  js  c++  java
  • Java与C#开发上的一些差异与转换方法

    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);
             }
  • 相关阅读:
    js验证表单大全
    JavaScript验证表单大全
    ASP.NET(c#)操作cookie、session、cache工具类
    AIX查看硬件配置
    SAP* DDIC密码丢失如何处理
    如何学好SAP BASIS
    SAP STMS 传输系统配置
    BOM展开实例
    免安装Oracle客户端使用PL/SQL连接Oracle
    入门培训SAP操作手册 之前台操作
  • 原文地址:https://www.cnblogs.com/AndyGe/p/3092130.html
Copyright © 2011-2022 走看看