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

时间:2024-01-15 23:59:44

1. 静态构造函数

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

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

 class Parent{
public static StaticVariable staticVariable = new StaticVariable("Parent - Static Variable1");
public StaticVariable inStaticVariable = new StaticVariable("Parent - Instant Variable1"); static
{
System.out.println("Parent - Static block/constructor");
System.out.println(staticVariable == null);
//System.out.println(staticVariable2 == null); not working because staticVariable2 is not defined
staticVariable2 = new StaticVariable("Parent - Static Variable2 - Static block");
} {
System.out.println("Parent - Initializer Block");
} public static StaticVariable staticVariable2 = new StaticVariable("Parent - Static Variable2");
public StaticVariable inStaticVariable2 = new StaticVariable("Parent - Instant Variable2"); public Parent()
{
System.out.println("Parent - Instance Constructor");
}
}

View Java Code

     class StaticDemo
{
static int i = ; static StaticDemo()
{
Console.WriteLine(i);
Console.WriteLine(j);
} public static void Execute()
{
} static int j = ;
}

View C# Code

2常量

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

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

Java Code and C# Code

 class ParentDef{
public static final String STATICVALUE_STRING="Parent Static Variable";
public String valueString="Parent Instant Variable";
} class ChildRef extends ParentDef{
public static final String STATICVALUE_STRING="Child Static Variable";
public String valueString="Child Instant Variable";
} public class BasicDemo {
public static void main(String[] args) {
//Child child = new Child(); ParentDef pdf = new ParentDef();
ParentDef pcdf = new ChildRef();
ChildRef cdf = new ChildRef();
System.out.println("V1");
System.out.println(pdf.STATICVALUE_STRING);
System.out.println(pdf.valueString); System.out.println("V2");
System.out.println(pcdf.STATICVALUE_STRING);
System.out.println(pcdf.valueString); System.out.println("V3");
System.out.println(cdf.STATICVALUE_STRING);
System.out.println(cdf.valueString); } }
     class InheritenceDemo
{
public static void Execute()
{
ParentDef pdf = new ParentDef();
ParentDef pc = new ChildDef();
ChildDef cdf = new ChildDef(); Console.WriteLine("V1");
Console.WriteLine(pdf.value); Console.WriteLine("V2");
Console.WriteLine(pc.value); Console.WriteLine("V3");
Console.WriteLine(cdf.value);
Console.WriteLine(cdf.READONLYSTRING); }
} class ParentDef
{
public const string Const_String = "Parent Const Varialbe";
public static string STATICVALUE_STRING = "Parent Static Variable";
public string value = "Parent Instant Variable";
} class ChildDef:ParentDef
{
public readonly string READONLYSTRING="Child readonly variable";
public readonly static string READONLYSTATICSTRING = "Child readonly static variable";
public static string STATICVALUE_STRING = "Child Static Variable";
public string value = "Child Instant Variable"; public ChildDef()
{
READONLYSTRING = "NEW Child readonly variable";
//READONLYSTATICSTRING = "NEW Child readonly static variable"; ERROR as satatic readonly variable can not be reassianged in instant constructor
}
}

3参数传递

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

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

C# code

  class RefExample
  {
  static void Method(ref int i)
  {
  i = ;
  }
  static void Main()
  {
  int val = ;
  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("","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()==) System.out.println("Input Name!!!");
for(int i = ;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并不是由编译器强制的。