zl程序教程

您现在的位置是:首页 >  后端

当前栏目

C# VS JAVA 差异 (未完待续)

JAVAc#vs 差异
2023-09-14 08:57:09 时间

1. 静态构造函数

C#中有静态构造函数, Java中没有静态构造函数。其实Java中有一个类似静态构造函数的东东,称作静态初始化,或者静态代码块,可以通过这样的代码实现相同的功能:

但是Java中静态代码块和C#静态构造函数还是不一样的。C#中静态构造函数在其他静态成员初始化后再执行,而java中静态代码块和其他静态成员谁在先谁就先执行。

 1 class Parent{
 2     public static StaticVariable staticVariable = new StaticVariable("Parent - Static Variable1");
 3     public StaticVariable inStaticVariable = new StaticVariable("Parent - Instant Variable1");
 4     
 5     static
 6     {
 7         System.out.println("Parent - Static block/constructor");
 8         System.out.println(staticVariable == null); 
 9         //System.out.println(staticVariable2 == null); not working because staticVariable2 is not defined
10         staticVariable2 = new StaticVariable("Parent - Static Variable2 -  Static block");
11     }
12     
13     {
14         System.out.println("Parent - Initializer Block");
15     }
16     
17     public static StaticVariable staticVariable2 = new StaticVariable("Parent - Static Variable2");
18     public StaticVariable inStaticVariable2 = new StaticVariable("Parent - Instant Variable2");
19     
20     public Parent()
21     {
22         System.out.println("Parent - Instance Constructor");
23     }
24 }
View Java Code

 

 1     class StaticDemo
 2     {
 3         static int i = 1;
 4 
 5         static StaticDemo() 
 6         {
 7             Console.WriteLine(i);
 8             Console.WriteLine(j);
 9         }
10 
11         public static void Execute()
12         {
13         }
14 
15         static int j = 1;
16     }
View C# Code

 

2常量

Java中声明(实例/)常量使用关键词(final/static final)。C#中声明(实例/类)常量使用关键词(readonly/const 或者 readonly static).

C#中必须使用类名去访问类层级的变量。Java中可以使用实例去访问类层级的变量,但是编译时会有警告。

Java Code and C# Code

 1 class ParentDef{
 2     public static final String STATICVALUE_STRING="Parent Static Variable";
 3     public String valueString="Parent Instant Variable";
 4 }
 5 
 6 class ChildRef extends ParentDef{
 7     public static final String STATICVALUE_STRING="Child Static Variable";
 8     public String valueString="Child Instant Variable";
 9 }
10 
11 public class BasicDemo {
12     public static void main(String[] args) {
13         //Child child = new Child();
14         
15         ParentDef pdf = new ParentDef();
16         ParentDef pcdf = new ChildRef();
17         ChildRef cdf = new ChildRef();
18         System.out.println("V1");
19         System.out.println(pdf.STATICVALUE_STRING);
20         System.out.println(pdf.valueString);
21         
22         System.out.println("V2");
23         System.out.println(pcdf.STATICVALUE_STRING);
24         System.out.println(pcdf.valueString);
25         
26         System.out.println("V3");
27         System.out.println(cdf.STATICVALUE_STRING);
28         System.out.println(cdf.valueString);
29         
30     }
31 
32 }
View Code
 1     class InheritenceDemo
 2     {
 3         public static void Execute() 
 4         {
 5             ParentDef pdf = new ParentDef();
 6             ParentDef pc = new ChildDef();
 7             ChildDef cdf = new ChildDef();
 8 
 9 
10             Console.WriteLine("V1");
11             Console.WriteLine(pdf.value);
12 
13     
14             Console.WriteLine("V2");
15             Console.WriteLine(pc.value);
16 
17             Console.WriteLine("V3");
18             Console.WriteLine(cdf.value);
19             Console.WriteLine(cdf.READONLYSTRING);
20 
21         }
22     }
23 
24     class ParentDef
25     {
26         public const string Const_String = "Parent Const Varialbe";
27         public static string STATICVALUE_STRING = "Parent Static Variable";
28         public string value = "Parent Instant Variable";
29     }
30 
31     class ChildDef:ParentDef
32     {
33         public readonly string READONLYSTRING="Child readonly variable";
34         public readonly static string READONLYSTATICSTRING = "Child readonly  static variable";
35         public static string STATICVALUE_STRING = "Child Static Variable";
36         public string value = "Child Instant Variable";
37 
38         public ChildDef() 
39         {
40             READONLYSTRING = "NEW Child readonly variable";
41             //READONLYSTATICSTRING = "NEW Child readonly  static variable"; ERROR as satatic readonly variable can not be reassianged in instant constructor
42         }
43     }
View Code

 

3参数传递

C#中有ref关键词用来按引用传递参数。Java则没有,无法真正按引用传递参数。Java总是采用按值调用。方法得到的是所有参数值的一个拷贝,特别的,方法不能修改传递给它的任何参数变量的内容。

(1):“在Java里面参数传递都是按值传递”这句话的意思是:按值传递是传递的值的拷贝,按引用传递其实传递的是引用的地址值,所以统称按值传递。
(2):在Java里面只有基本类型和按照下面这种定义方式的String是按值传递,其它的都是按引用传递。就是直接使用双引号定义字符串方式:String str = “Java”;

C# code

  class RefExample 
  { 
  static void Method(ref int i) 
  { 
  i = 44; 
  } 
  static void Main() 
  { 
  int val = 0; 
  Method(ref val); // val is now 44 
  } 
  }

 

4虚函数

C#中普通成员函数加上virtual关键字就成为虚函数.

Java中其实没有虚函数的概念,它的普通函数就相当于C#的虚函数,动态绑定是Java的默认行为。如果Java中不希望某个函数具有虚函数特性,可以加上final关键字变成非虚函数.

 

5空接口

在Java和C#中空接口都是合法的。都可以定义空接口。空接口还是很奇怪的存在,个人的理解是空接口仅做标记使用,无其他含义。如果你只需要在运行时区分这些类型,一个更佳的解决方式是使用自定义属性(attribute)。如果你希望在编译时区分这些类型,就只好使用空接口了。 而JDK中定义的很多空接口很多都是前者,个人认为这是一种不良的设计,反观CLR,我们则很难找到一个空接口。 所以.Net的设计在这点上来看跟合理点。
JDK中定义的空接口
java.io.Serializable;
java.lang.Cloneable
java.lang.annotation.Annotation;
java.rmi.Remote;
java.util.RandomAccess;

 

6Delegate 和 Event

Java欠缺C#中的事件功能,java中没有delegate这种用法。在java中实现事件功能其实就是通过实现EventListener接口实现观察者模式。C#则是通过EventHandler的实例来实现事件的功能。

class EventDemo
    {
        public static void RunDemo()
        {
            SMS sms = new SMS();
            SmsReceiver r = new SmsReceiver(sms);
            sms.SendSms("188288388","Hello world");
        }
    }

    public class SMS
    {
        public EventHandler<SmsEventArgs> SmsEvent = (o, e) => { };
        public EventHandler SmsEvent2;

        protected virtual void OnSmsEvent(SmsEventArgs e)
        {
            //EventHandler<SmsEventArgs> handler = this.SmsEvent;
            //if (handler != null)
            //{
            //    handler(this, e);
            //}

            this.SmsEvent(this, e);

        }

        protected virtual void OnSmsEvent2()
        {
            EventHandler handler = this.SmsEvent2;

            if (handler != null)
            {
                handler(this,null);
            }
        }


        public void SendSms(string phone, string message)
        {
            SmsEventArgs e = new SmsEventArgs();
            e.Message = message;
            e.ToPhone = phone;
            OnSmsEvent(e);
        }
    }

    public class SmsEventArgs:EventArgs
    {
        public string ToPhone { get; set; }
        public string Message { get; set; }
    }

    public class SmsReceiver
    {
        public SmsReceiver(SMS sms)
        {
            sms.SmsEvent += new EventHandler<SmsEventArgs>(sms_SmsEvent);
        }

        void sms_SmsEvent(object sender, SmsEventArgs e)
        {
            Console.WriteLine(e.ToPhone + ":" + e.Message);
        }
 
    }
View C# Code

 

public class AskEvent extends EventObject {

    private static final long serialVersionUID = 1L;  
    private Object Evnetsource;  
    private String name; 
    
    
    public Object getEvnetsource() {
        return Evnetsource;
    }
    
    public String getName() {
        return name;
    }
     
    public AskEvent(Object source,String name) {
        super(source);
        Evnetsource = source;
        this.name = name;
    }

}

public interface Listener extends EventListener {
    public void listen(AskEvent ae); 

}

public class Ask {

        private Listener l ;
        private List<String> names = new ArrayList<String>();
        
        public void addListener(Listener l){
            this.l = l;
        }
        
        public void addName(String name){
            names.add(name);
        }
        
        public void setFlag(boolean flag){
            if(flag){
                if(names.size()==0) System.out.println("Input Name!!!");
                for(int i = 0;i<names.size();i++){
                    l.listen(new AskEvent(this,names.get(i)));
                }
                names.clear();
            }
        }
        
}


public class EventTest {

    public static void main(String[] args) {
        System.out.println("START");  
        Scanner scan = new Scanner(System.in);  
        Ask ask = new Ask();  
         ask.addListener(new Listener(){  
             public void listen(AskEvent ae) { 
                 if(ae.getName().equals("a")) System.out.println(ae.getName() + "good man");  
                 else System.out.println(ae.getName() + "bad man");  
             }
         });
         
         while(true){
                System.out.print("input name:");
                final String name = scan.nextLine();
                if(name.equals("exit")) break;
                if(name.equals("print")) {
                    ask.setFlag(true);
                    continue;
                }
                ask.addName(name);
            }
            System.out.println("OVER");
        }
    }
View Java Code

 

7Exception

Java中Checked Exception是必须要被try_catch捕获,编译器会强制检查的。在C#中是否捕获Exception并不是由编译器强制的。