Java'da derleme zamanı ve çalışma zamanı bağımlılıkları arasındaki fark nedir? Sınıf yolu ile ilgilidir, ancak bunlar nasıl farklıdır?
Yanıtlar:
Derleme zamanı bağımlılığı : Yapınızı derlemek için bağımlılığa ihtiyacınız var CLASSPATH
. Bunlar, kodunuzda sabit kodlanmış bağımlılık için bir tür "referansa" sahip olduğunuz için üretilir; örneğin, new
bir sınıfı çağırmak , bir şeyi genişletmek veya uygulamak (doğrudan veya dolaylı olarak) veya doğrudan reference.method()
gösterimi kullanan bir yöntem çağrısı gibi .
Çalışma zamanı bağımlılığı : CLASSPATH
Yapınızı çalıştırmak için kendi bağımlılığınıza ihtiyacınız var . Bağımlılığa erişen kodu yürüttüğünüz için üretilirler (ya kodlanmış bir şekilde ya da yansıtma yoluyla ya da her neyse).
Derleme zamanı bağımlılığı genellikle çalışma zamanı bağımlılığı anlamına gelse de, yalnızca derleme zamanı bağımlılığınız olabilir. Bu, Java'nın yalnızca sınıf bağımlılıklarını o sınıfa ilk erişime bağladığı gerçeğine dayanmaktadır; bu nedenle, bir kod yolu hiçbir zaman geçilmediği için çalışma zamanında belirli bir sınıfa asla erişmezseniz, Java hem sınıfı hem de bağımlılıklarını göz ardı eder.
Bunun örneği
C. java'da (C.class oluşturur):
package dependencies;
public class C { }
A. java'da (A. sınıfını üretir):
package dependencies;
public class A {
public static class B {
public String toString() {
C c = new C();
return c.toString();
}
}
public static void main(String[] args) {
if (args.length > 0) {
B b = new B();
System.out.println(b.toString());
}
}
}
Bu durumda, A
bir derleme zamanı bağımlılığı olan C
through B
, ancak yürütme bazı parametreleri geçmesi durumunda sadece C üzerinde çalışma zamanı bağımlılığı olacak java dependencies.A
JVM sadece çözmeye çalışacağı gibi B
hakkında yaptığı bağımlılığını C
o yürütmek için aldığında B b = new B()
. Bu özellik, çalışma zamanında yalnızca kod yollarınızda kullandığınız sınıfların bağımlılıklarını sağlamanıza ve yapıdaki diğer sınıfların bağımlılıklarını yok saymanıza olanak tanır.
Kolay bir örnek, servlet api gibi bir api'ye bakmaktır. Sunucu uygulamalarınızın derlenmesini sağlamak için, servlet-api.jar dosyasına ihtiyacınız vardır, ancak çalışma zamanında servlet kapsayıcısı bir servlet api uygulaması sağlar, böylece çalışma zamanı sınıf yolunuza servlet-api.jar eklemeniz gerekmez.
Derleyicinin bir kitaplığa çağrıları derlemek için doğru sınıf yoluna ihtiyacı vardır (derleme zamanı bağımlılıkları)
JVM, çağırdığınız kitaplıktaki sınıfları yüklemek için doğru sınıf yoluna ihtiyaç duyar (çalışma zamanı bağımlılıkları).
Birkaç yönden farklı olabilirler:
1) C1 sınıfınız L1 kitaplık sınıfını ve L1 kitaplık sınıfını L2'yi çağırırsa, C1'in L1 ve L2'ye bir çalışma zamanı bağımlılığı vardır, ancak L1'e yalnızca derleme süresi bağımlılığı vardır.
2) C1 sınıfınız Class.forName () veya başka bir mekanizma kullanarak bir I1 arabirimini dinamik olarak başlatırsa ve arabirim I1 için uygulama sınıfı sınıf L1 ise, C1'in I1 ve L1'e bir çalışma zamanı bağımlılığı vardır, ancak yalnızca bir derleme zamanı bağımlılığı vardır. I1'de.
Derleme zamanı ve çalışma zamanı için aynı olan diğer "dolaylı" bağımlılıklar:
3) C1 sınıfınız L1 kitaplık sınıfını genişletir ve L1, I1 arabirimini uygular ve kitaplık sınıfı L2'yi genişletir: C1, L1, L2 ve I1'e derleme zamanı bağımlılığına sahiptir.
4) C1 sınıfınızın bir yöntemi foo(I1 i1)
ve bar(L1 l1)
I1'in bir arabirim olduğu ve L1'in I1 arabirimi olan bir parametre alan bir sınıf olduğu bir yöntem vardır: C1, I1 ve L1'e derleme zamanı bağımlılığına sahiptir.
Temel olarak, ilginç bir şey yapmak için, sınıfınızın sınıf yolundaki diğer sınıflar ve arabirimlerle arayüz oluşturması gerekir. Bu kitaplık arabirimleri kümesi tarafından oluşturulan sınıf / arabirim grafiği , derleme zamanı bağımlılık zincirini verir. Kitaplık uygulamaları , çalışma zamanı bağımlılık zincirini verir. Çalışma zamanı bağımlılık zincirinin çalışma zamanına bağlı veya başarısız-yavaş olduğuna dikkat edin: L1 uygulaması bazen L2 sınıfının bir nesnesinin somutlaştırılmasına bağlıysa ve bu sınıf yalnızca belirli bir senaryoda somutlaştırılırsa, bu durumda aşağıdakiler dışında hiçbir bağımlılık yoktur bu senaryo.
Java aslında derleme zamanında hiçbir şeyi bağlamaz. Yalnızca CLASSPATH'da bulduğu eşleşen sınıfları kullanarak sözdizimini doğrular. Her şeyin bir araya getirilmesi ve o sırada CLASSPATH'a göre yürütülmesi çalışma zamanına kadar değildir.
Derleme zamanı bağımlılıkları yalnızca doğrudan derlediğiniz sınıfta kullandığınız bağımlılıklardır (diğer sınıflar) . Çalışma zamanı bağımlılıkları, çalıştırdığınız sınıfın hem doğrudan hem de dolaylı bağımlılıklarını kapsar. Bu nedenle, çalışma zamanı bağımlılıkları, bağımlılıkların bağımlılıklarını ve a'da sahip olduğunuz String
, ancak içinde kullanılan sınıf adları gibi yansıma bağımlılıklarını içerir Class#forName()
.
A
, B.jar ile B extends A
ve C.jar ile birlikte varsa, C extends B
o zaman C.jar, A'ya C bağımlılığı dolaylı olsa da, A.jar üzerinde derleme süresine bağlıdır.
Java için derleme zamanı bağımlılığı, kaynak kodunuzun bağımlılığıdır. Örneğin, A sınıfı B sınıfından bir yöntemi çağırırsa, derleme zamanında A B'ye bağımlıdır, çünkü A'nın derlenecek B'yi (B türü) bilmesi gerekir. Buradaki hile şu olmalıdır: Derlenmiş kod henüz tam ve çalıştırılabilir bir kod değildir. Henüz derlenmemiş veya harici kavanozlarda mevcut olmayan kaynaklar için değiştirilebilir adresler (semboller, meta veriler) içerir. Bağlanma sırasında, bu adresler bellekteki gerçek adreslerle değiştirilmelidir. Bunu düzgün yapmak için doğru semboller / adresler oluşturulmalıdır. Ve bu (B) sınıfının türü ile yapılabilir. Derleme zamanındaki ana bağımlılığın bu olduğuna inanıyorum.
Çalışma zamanı bağımlılığı daha çok gerçek kontrol akışıyla ilgilidir. Gerçek hafıza adreslerini çağırır. Programınız çalışırken sahip olduğunuz bir bağımlılıktır. Burada yalnızca tür bilgileri değil, uygulamalar gibi B sınıfı ayrıntılara da ihtiyacınız var. Sınıf mevcut değilse, RuntimeException alırsınız ve JVM çıkar.
Her iki bağımlılık da, genellikle ve olmamalıdır, aynı yönde akar. Bu bir OO tasarım meselesidir.
C ++ 'da, derleme biraz farklıdır (tam zamanında değil) ancak bir bağlayıcı da vardır. Yani süreç sanırım Java'ya benzer düşünülebilir.