.Net'te yeniyim ve önce temelleri anlamaya çalışıyorum. MSIL ve Java bayt kodu arasındaki fark nedir?
.Net'te yeniyim ve önce temelleri anlamaya çalışıyorum. MSIL ve Java bayt kodu arasındaki fark nedir?
Yanıtlar:
Öncelikle, Java bayt kodu ve MSIL arasındaki ince farkların acemi bir .NET geliştiricisini rahatsız etmesi gereken bir şey olduğunu düşünmediğimi söylememe izin verin. Her ikisi de, sonunda kullanılan fiziksel makinenin üzerindeki bir katman olan soyut bir hedef makineyi tanımlamak için aynı amaca hizmet eder.
MSIL ve Java bayt kodu çok benzer, aslında Grasshopper adında MSIL'i Java bayt koduna çeviren bir araç var, Grasshopper geliştirme ekibinin bir parçasıydım, böylece (soluk) bilgilerimi biraz paylaşabilirim. NET framework 2.0 çıktığında bu konu üzerinde çalışmayı bıraktığımı lütfen unutmayın, bu yüzden bunlardan bazıları artık doğru olmayabilir (eğer öyleyse lütfen bir yorum bırakın ve ben düzelteceğim).
struct
) ek olarak değer semantiğine sahip kullanıcı tanımlı türlere izin verir .enums
ise çok daha tamsayı türlerinden etrafında sarmalayıcıları daha olmayan Javaenums
(sayesinde hemen hemen tam teşekkülü sınıfları şunlardır İnternet Arkadaşlar yorumlama için).out
ve ref
parametreleri.Başka dil farklılıkları da vardır, ancak bunların çoğu bayt kodu seviyesinde ifade edilmez, örneğin bellek Java'nın static
iç olmayan sınıflarına (.NET'te bulunmayan) bir bayt kodu özelliği sunmuyorsa, derleyici ek bir argüman oluşturur. iç sınıfın yapıcısı ve dış nesneyi iletir. Aynısı .NET lambda ifadeleri için de geçerlidir.
CIL (MSIL için doğru isim) ve Java bayt kodu, farklı olduklarından daha fazla aynıdır. Yine de bazı önemli farklılıklar var:
1) CIL, başından beri birden çok dil için bir hedef olarak hizmet etmek üzere tasarlanmıştır. Bu nedenle, imzalı ve işaretsiz türler, değer türleri, işaretçiler, özellikler, temsilciler, olaylar, jenerikler, tek kökü olan bir nesne sistemi ve daha fazlasını içeren çok daha zengin bir tür sistemini destekler. CIL, global işlevler ve kuyruk arama optimizasyonları gibi ilk CLR dilleri (C # ve VB.NET) için gerekli olmayan özellikleri destekler . Karşılaştırıldığında, Java bayt kodu Java dili için bir hedef olarak tasarlanmıştır ve Java'nın kendisinde bulunan kısıtlamaların çoğunu yansıtır. Java bayt kodu kullanarak C veya Şema yazmak çok daha zor olurdu.
2) CIL, yerel kitaplıklara ve yönetilmeyen koda kolayca entegre olacak şekilde tasarlanmıştır
3) Java bayt kodu yorumlanacak veya derlenecek şekilde tasarlanırken, CIL yalnızca JIT derlemesi varsayılarak tasarlandı. Bununla birlikte, Mono'nun ilk uygulaması bir JIT yerine bir yorumlayıcı kullandı.
4) CIL, doğrudan bayt kodu formuyla eşleşen, insan tarafından okunabilir ve yazılabilir bir montaj dili formuna sahip olacak şekilde tasarlanmış ( ve belirtilmiştir ). Java bayt kodunun (adından da anlaşılacağı gibi) yalnızca makine tarafından okunabilir olması gerektiğine inanıyorum. Elbette, Java bayt kodu, orijinal Java'ya nispeten kolay bir şekilde geri derlenebilir ve aşağıda gösterildiği gibi, aynı zamanda "parçalarına ayrılabilir".
JVM'nin (çoğu) CLR'den (herhangi biri) daha yüksek düzeyde optimize edildiğine dikkat etmeliyim. Bu nedenle, ham performans Java bayt kodunu hedeflemeyi tercih etmek için bir neden olabilir. Bu bir uygulama detayıdır.
Bazı insanlar Java bayt kodunun çoklu platform olarak tasarlandığını, CIL ise yalnızca Windows için tasarlandığını söylüyor. Durum bu değil. .NET çerçevesinde bazı "Windows" ismleri vardır ancak CIL'de yoktur.
Yukarıdaki 4) numaralı noktaya örnek olarak, bir süre önce bir Java to CIL derleyicisine bir oyuncak yazdım. Bu derleyiciyi aşağıdaki Java programını beslerseniz:
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 ;
}
}
derleyicim aşağıdaki CIL'yi çıkaracak:
.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
}
}
Bu, ilasm.exe
bir yürütülebilir dosya oluşturmak gibi bir CIL derleyicisine beslenebilen geçerli bir CIL programıdır . Gördüğünüz gibi, CIL tamamen okunabilir ve yazılabilir bir dildir. Herhangi bir metin düzenleyicide kolayca geçerli CIL programları oluşturabilirsiniz.
Ayrıca yukarıdaki Java programını javac
derleyiciyle derleyebilir ve ardından ortaya çıkan sınıf dosyalarını javap
"disassembler" aracılığıyla çalıştırarak aşağıdakileri elde edebilirsiniz:
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
}
javap
Çıkışı (bildiğim kadarıyla) derlenebilir değil ama CIL çıkışına karşılaştırmak takdirde iki çok benzer olduğunu görebilirsiniz yukarıda.
Esasen aynı şeyi yapıyorlar, MSIL, Microsoft'un Java bayt kodu sürümüdür.
Dahili olarak temel farklılıklar şunlardır:
Bu makalede çok daha fazla bilgi ve ayrıntılı bir karşılaştırma K John Gough tarafından bulunabilir (postscript belgesi)
CIL aka MSIL, insan tarafından okunabilir olması amaçlanmıştır. Java bayt kodu değil.
Java bayt kodunu, var olmayan (ancak JVM'lerin taklit ettiği) donanım için makine kodu olarak düşünün.
CIL daha çok assembly dili gibidir - makine kodundan bir adım ötede, yine de insan tarafından okunabilir.
O kadar çok fark yok. Her ikisi de yazdığınız kodun ara biçimleridir. Çalıştırıldığında, Sanal makineler yönetilen ara dili çalıştırır, bu da Sanal Makinenin değişkenleri ve çağrıları kontrol ettiği anlamına gelir. Şu anda hatırlamadığım, .Net ve Java'da aynı şekilde çalışabilen bir dil bile var.
Temel olarak, aynı şey için başka bir format
Düzenleme: Dili buldum (Scala dışında): FAN ( http://www.fandev.org/ ), çok ilginç görünüyor, ancak henüz değerlendirmek için zaman yok
Kabul edildi, farklılıklar yeni başlayanlar için yeterince küçük. Eğer temelden başlayarak .Net öğrenmek istiyorsanız, Ortak Dil Altyapısına ve Ortak Tip Sistemine bakmanızı tavsiye ederim.
Serge Lidin, MSIL: Expert .NET 2.0 IL Assembler'ın ayrıntıları üzerine iyi bir kitap yazdı . Ayrıca .NET Reflector ve Ildasm (Eğitim) kullanarak basit yöntemlere bakarak MSIL'i hızlı bir şekilde alabildim .
MSIL ve Java bayt kodu arasındaki kavramlar çok benzer.
Bence MSIL, Java bayt kodu ile değil, "Java bayt kodlarını içeren talimat" ile karşılaştırılmalıdır.
Parçalanmış java bayt kodunun adı yoktur. Adını resmi belgede bulamadığım için "Java Bytecode" resmi olmayan bir takma ad olmalıdır. Java Sınıfı Dosya Dağıtıcı diyor ki
Sınıftaki yöntemlerin her biri için demonte edilmiş kodu, yani Java bayt kodlarını içeren talimatları yazdırır. Bunlar, Java Sanal Makine Belirtiminde belgelenmiştir.
Hem "Java VM talimatları" hem de "MSIL", .NET bayt kodu ve Java kodunda bir araya getirilmiştir ve bunlar insan tarafından okunamaz.