C#(.Net)编译器和Java编译器技术有哪些区别?

4

我的教授问了我们这个问题:C#(.Net)编译器和Java编译器技术有什么区别?


2
为什么不问你的大学老师呢? - Shoban
4
SO的政策是允许发布可以在谷歌上搜索到答案的问题。请不要打击他人的积极性。谁知道你可能会从答案中获得一两个你之前不知道的知识点! - Srinivas Reddy Thatiparthy
4个回答

3
Java和C#编译器都会编译成中间虚拟机的“机器码”,该虚拟机与最终执行平台无关,分别是JVM和CLR。
JVM最初只是为了支持Java而设计的。虽然可以将除Java以外的语言编译为在JVM上运行的代码,但其设计中存在某些不完全适合于特定类别语言的方面。相比之下,CLR及其指令集从一开始就被设计用于支持多种语言。
另一个区别在于JIT编译的工作方式。根据维基百科,CLR被设计为运行完全编译的代码,因此(可能)CLR的JIT编译器必须在启动之前急切地编译整个应用程序。(我还了解到,您可以提前将字节码编译为本机代码。)相比之下,Hotspot JVM使用真正的“即时”编译。字节码方法最初由JVM使用字节码解释器执行,该解释器还会收集有关方法中采取的执行路径的跟踪信息。那些多次执行的方法然后通过JIT编译器编译为本机代码,使用捕获的跟踪信息帮助代码优化。这允许本机代码针对实际执行平台进行优化,甚至针对当前应用程序的行为进行优化。
当然,C#和Java语言有许多重要的差异,并且由于需要处理这些语言差异,相应的编译器也不同。例如,一些C#编译器执行更多的类型推断...因为相应的C#语言版本更依赖于推断类型。(请注意,Java和C#语言都随着时间的推移而发展。)

0

就编译器而言,除了显而易见的“输入”和“输出”之外,我能想到的最大区别是泛型实现方式,因为两者都有泛型,但非常不同(类型擦除 vs 运行时辅助)。装箱模型显然是不同的,但我不确定对于编译器来说是否很重要。

在匿名方法、匿名内部类、lambda 表达式、委托等方面,明显存在特性差异,但很难进行1:1比较。尽管如此,最终只有您的教授知道他寻求的答案(对教授表示敬意,但不一定会惊讶他的答案已经过时了一年或更久)。


我认为类型擦除实际上更多是代码生成问题,因此两个编译器中的泛型实现可能是相似的。 - Gabe

0

一个区别是C#编译器具有一些类型推断的能力,而Java编译器没有(尽管Java 7可能会改变这一点)。举个简单的例子,在Java中,你必须输入Map<String, List<String>> anagrams = new HashMap<String, List<String>>();,而在C#中,你可以使用var anagrams = new HashMap<String, List<String>>();(尽管你可以在C#中创建非常大、复杂的表达式,而不必命名类型)。

另一个区别是C#编译器可以创建表达式树,使您能够将一个函数的描述传递给另一个函数。例如,(Func<int,int>) x => x * 2是一个函数,它接受一个整数并将其加倍,而(Expression<Func<int,int>>) x => x * 2是一个数据结构,描述了一个接受一个整数并将其加倍的函数。您可以将此描述编译成一个函数(在本地运行)或将其翻译成SQL(作为数据库查询的一部分运行)。


非常好的解释。谢谢。 - Chintan Shah

-1

对于Java来说,这比较了CLR和JVM(尽管我对.NET不是很了解,但我敢说它基本相同),编译器与JVM是非常不同和独立的存在。 - Reese Moore

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接