Mot*_*tti 73
首先请允许我说,我不认为Java字节码和MSIL之间的细微差别应该是新手.NET开发人员的烦恼.它们都用于定义抽象目标机器的相同目的,该机器是最终使用的物理机器之上的层.
MSIL和Java字节码非常相似,实际上有一个名为Grasshopper的工具可以将MSIL转换为Java字节码,我是Grasshopper开发团队的一员,因此我可以分享一些我的(褪色)知识.请注意,当.NET framework 2.0问世时,我已经停止了这方面的工作,因此其中一些事情可能不再适用(如果是这样,请发表评论,我会更正).
struct
)相关的值语义.enums
不仅仅是整数类型的包装器,而Javaenums
几乎是完全成熟的类(感谢Internet Friend的评论).out
和ref
参数.还有其他语言差异,但大部分都没有在字节代码级别表达,例如,如果内存服务于Java的非static
内部类(.NET中不存在)不是字节码功能,则编译器会生成一个额外的参数内部类的构造函数并传递外部对象..NET lambda表达式也是如此.
Guy*_*uck 22
它们本质上是做同样的事情,MSIL是微软的Java字节码版本.
内部的主要区别是:
K John Gough在本文中可以找到更多的信息和详细的比较(后记文件)
Jus*_*tin 20
CIL(MSIL的正确名称)和Java字节码比它们不同的更相同.但是有一些重要的区别:
1)CIL从一开始就被设计为多语言的目标.因此,它支持更丰富的类型系统,包括有符号和无符号类型,值类型,指针,属性,委托,事件,泛型,具有单个根的对象系统等.CIL支持初始CLR语言(C#和VB.NET)不需要的功能,例如全局函数和尾调用优化.相比之下,Java字节码被设计为Java语言的目标,并反映了Java本身的许多约束.使用Java字节码编写C或Scheme会困难得多.
2)CIL旨在轻松集成到本机库和非托管代码中
3)Java字节码被设计为解释或编译,而CIL的设计仅假设JIT编译.也就是说,Mono的初始实现使用了解释器而不是JIT.
4)CIL被设计(并指定)为具有人类可读和可写的汇编语言形式,其直接映射到字节码形式.我相信Java字节码(顾名思义)只是机器可读的.当然,Java字节码相对容易反编译回原始Java,如下所示,它也可以"反汇编".
我应该注意到JVM(大多数)比CLR(其中任何一个)都更加优化.因此,原始性能可能是更喜欢使用Java字节码的原因.这是一个实现细节.
有人说Java字节码设计为多平台,而CIL只设计为Windows.不是这种情况..NET框架中有一些"Windows"主义,但CIL中没有.
作为上面第4点的一个例子,我曾经写过一个玩具Java到CIL编译器.如果您为此编译器提供以下Java程序:
class Factorial{
public static void main(String[] a){
System.out.println(new Fac().ComputeFac(10));
}
}
class Fac {
public int ComputeFac(int num){
int num_aux ;
if (num < 1)
num_aux = 1 ;
else
num_aux = num * (this.ComputeFac(num-1)) ;
return num_aux ;
}
}
Run Code Online (Sandbox Code Playgroud)
我的编译器将吐出以下CIL:
.assembly extern mscorlib { }
.assembly 'Factorial' { .ver 0:0:0:0 }
.class private auto ansi beforefieldinit Factorial extends [mscorlib]System.Object
{
.method public static default void main (string[] a) cil managed
{
.entrypoint
.maxstack 16
newobj instance void class Fac::'.ctor'()
ldc.i4 3
callvirt instance int32 class Fac::ComputeFac (int32)
call void class [mscorlib]System.Console::WriteLine(int32)
ret
}
}
.class private Fac extends [mscorlib]System.Object
{
.method public instance default void '.ctor' () cil managed
{
ldarg.0
call instance void object::'.ctor'()
ret
}
.method public int32 ComputeFac(int32 num) cil managed
{
.locals init ( int32 num_aux )
ldarg num
ldc.i4 1
clt
brfalse L1
ldc.i4 1
stloc num_aux
br L2
L1:
ldarg num
ldarg.0
ldarg num
ldc.i4 1
sub
callvirt instance int32 class Fac::ComputeFac (int32)
mul
stloc num_aux
L2:
ldloc num_aux
ret
}
}
Run Code Online (Sandbox Code Playgroud)
这是一个有效的CIL程序,可以输入CIL汇编程序,就像ilasm.exe
创建一个可执行文件.如您所见,CIL是一种完全人类可读写的语言.您可以在任何文本编辑器中轻松创建有效的CIL程序.
您还可以使用编译javac
器编译上面的Java程序,然后通过javap
"反汇编程序" 运行生成的类文件以获取以下内容:
class Factorial extends java.lang.Object{
Factorial();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
3: new #3; //class Fac
6: dup
7: invokespecial #4; //Method Fac."<init>":()V
10: bipush 10
12: invokevirtual #5; //Method Fac.ComputeFac:(I)I
15: invokevirtual #6; //Method java/io/PrintStream.println:(I)V
18: return
}
class Fac extends java.lang.Object{
Fac();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
public int ComputeFac(int);
Code:
0: iload_1
1: iconst_1
2: if_icmpge 10
5: iconst_1
6: istore_2
7: goto 20
10: iload_1
11: aload_0
12: iload_1
13: iconst_1
14: isub
15: invokevirtual #2; //Method ComputeFac:(I)I
18: imul
19: istore_2
20: iload_2
21: ireturn
}
Run Code Online (Sandbox Code Playgroud)
该javap
输出不编译(据我所知),但如果你把它比作CIL输出上面可以看到两个非常相似.
没有那么多差异。两者都是您编写的代码的中间格式。执行时,虚拟机将执行托管的中间语言,这意味着虚拟机控制变量和调用。甚至有一种我现在不记得的语言可以以同样的方式在 .Net 和 Java 上运行。
基本上,它只是同一事物的另一种格式
编辑:找到了语言(除了 Scala):它是 FAN(http://www.fandev.org/),看起来很有趣,但还没有时间评估
归档时间: |
|
查看次数: |
21627 次 |
最近记录: |