Java程序向.NET移植过程中的笔记
发表于2008年11月20日移植TE过程中遇到了一些Java与.NET平台的差异而产生的问题,在此记录。.NET中一些“隐藏功能”在这个过程中得到了很好的应用。
这里采用手工移植的方式,也可以尝试JLCA等自动转换工具。参见MSDN Magazine上的介绍JLCA使用案例的文章。
有关Java与.Net异同的一篇采访,A Conversation with Anders Hejlsberg(C#设计者) by Bill Venners with Bruce Eckel(Thinking in Java作者)。
final vs virtual
Java中除静态函数以外的方法默认都是虚函数,都可以被覆写,需要使用final关键字标记使其不能被覆写。但也有更准确的解释。
C#中必须用virtual关键字显式的声明一个方法可被覆写。第一个原因是性能,更重要的原因是版本。更具体的解释且看Anders Hejlsberg,Bruce Eckel等人的谈话。
final vs sealed
Java中可以使用final关键字标记类,使其不能被继承。
而.Net中使用sealed。对于类也可以用static关键字(会被自动编译为sealed)来防止被派生。
public class Test { Integer testField; Integer methodA() { return testField; } final Integer methodB() { return testField; } } class Test1 extends Test { @Override Integer methodA() { return 1; } @Override // error, it can not be overrided Integer methodB(){ return 2; } }
Descriptor
Java中的Descriptor可以用字符串的形式描述字段和方法的类型。但在.Net中我没有类似的东西(如果有请告知)。通过反射查看.Net Assembly可以看到的方法完整的信息,例如变量、参数等。只是没有一个类似Java Descriptor的东西。囧
多线程(Multiple Thread)
Java中需要实现Java.Lang.Runnable接口
.Net多线程只需要将一个方法赋给ThreadStart这个代理然后传给Thread并且调用Thread.Start()方法。
相对而言后者有更好的同步或者异步的支持。.Net多线程有一个不错的在线教程。
Exception
InvalidOperationException == IllegalStateException
implicit & explicit
implicit是一个关键字,实现隐式转换
namespace implicitExample { class Digit { public Digit(double d) { val = d; } public double val; // ...other members // User-defined conversion from Digit to double public static implicit operator double(Digit d) { return d.val; } // User-defined conversion from double to Digit public static implicit operator Digit(double d) { return new Digit(d); } } class Program { static void Main(string[] args) { Digit dig = new Digit(7); //This call invokes the implicit "double" operator double num = dig; //This call invokes the implicit "Digit" operator Digit dig2 = 12; Console.WriteLine("num = {0} dig2 = {1}", num, dig2.val); Console.ReadLine(); } } }
泛型,泛型集合(Generic & Generic Collection)
Java的泛型,在处理泛型集合时会遇到可写不可写的情况,参看这个讨论。
List<?> // 类型未知,只能添加null List<? extends Number> // 类型未知,限定为Number的派生类,只能添加null List<? super Double> // 类型位置,限定为Double的基类,可以添加元素
方形方法的例子
void recordNonOveridableMethodCall(Reason reason, int lineNumber, MethodInfo toMethod, Variable methodThis, List parameters, Variable returnVariable) { //... }
.NET的泛型
void recordNonOveridableMethodCall(Reason reason, int lineNumber, MethodInfo toMethod, Variable methodThis, List parameters, Variable returnVariable) where T : Variable{ //... }
嵌套类(Nested Class in Java, Inner Class in .Net)
.Net中嵌套类与Java中的有很大不同,内部类只能访问到外部类的静态字段、属性和方法。
而Java中则都可以访问。
class OuterClass { private static int outerStaticField; private int outerField; class InnerClass { InnerClass() { outerStaticField = 1; //outerField = 1; // compile time error } } }
TreeSet
java.util.TreeSet之类的集合在.NET Framework中没有找到对应的实现,C5这个项目提供了大量的数据结构实现。需要调研并加以采用。目前用到了TreeSet这个红白树(Red-Black tree)实现。