Arasındaki fark nedir gerektirir ve geçişli gerektirir Modül beyanında modül ifadeleri?
Örneğin:
module foo {
requires java.base;
requires transitive java.compiler;
}
Arasındaki fark nedir gerektirir ve geçişli gerektirir Modül beyanında modül ifadeleri?
Örneğin:
module foo {
requires java.base;
requires transitive java.compiler;
}
Eğer modülü bar requires
modül içkiDaha sonra modül sistemi ...
Tam olarak aynı olur eğer bar requires transitive drink
- içki mevcut olmalı, okunabilir ve erişilebilir. Aslında bar ve içki transitive
anahtar kelime hiçbir şeyi değiştirmez.
Modüller bağlı olarak bar tarafından etkilenenler transitive
: Okuyan herhangi bir modül bar ayrıca okuyabilir içki. Başka bir deyişle okunabilirlik içki olduğu ima edilen (bu yüzden bu denir zımni okunabilirlik). Bunun bir sonucu müşteri erişilebilir içkiTürleri
Eğer öyleyse bar requires transitive drink
ve customer requires bar
, sonra müşteri okuyabilir içki Açıkça ona bağlı olmamasına rağmen.
Ama neden? Genel API'nin başka bir modülün türünü kabul ettiği veya döndürdüğü bir modülünüz olduğunu düşünün. Diyelim bar modül genel olarak örneklerini döndürür Drink
, bir arayüz içki modülü:
// in module _bar_
public class Bar {
// `Drink` comes from the module _drink_,
// which _bar_ requires
public Drink buyDrink() { /* ... */ }
}
Bu örnekte, bar düzenli kullanır requires
için içki. Şimdi söyle, müşteri bağlıdır barYani tüm kodu arayabilir Bar::buyDrink
. Ama ne zaman olur?
Modül sistemi bundan şikayet ediyor müşteri okumaz içki ve bu yüzden erişemez Drink
. Bunu düzeltmek için müşteri ayrıca güvenmek zorunda içki. Ne garip! Ne kadar işe yaramaz, hemen kullanamayacağın bir bar mı?
Bu nedenle, okunabilir okunabilirlik sağlandı: kendi API'sinde başka bir modülün türlerini kullanan bir modül oluşturmak için anında kullanılabilir olmadan arayanın avlanmasını ve tüm ilgili modülleri gerektirmesini gerektirir.
Eğer öyleyse bar requires transitive drink
, müşteri içmeden içki almaya başlayabilir require drink
- require bar
yeterli. Olması gerektiği gibi.
İkisi arasındaki birincil fark, bağımlı bir modülün bir diğerine erişmesidir.
Bir modül, imzası olan bir türü içeren bir paketi verirse ikinci bir modülde bir paketi ifade eder, daha sonra beyanı İlk modül bir içermelidir
requires transitive
bağımlılık ikinci. Bu bağlı diğer modülleri sağlayacaktır İlk modül otomatik olarak ikinci modülü okuyabilecek ve, bu nedenle, modülün dışa aktarılan paketlerindeki tüm türlere erişin.
Yani kullanım durumunuz için diyelim: -
module foo {
requires java.base;
requires transitive java.compiler;
}
~> Herhangi bir modül foo
modül otomatik olarak okuyacaktır java.compiler
modül
~> Modüle erişmek için java.base
belirtmelidirler requires
tekrar fıkra.
module bar {
requires foo; // java.compiler is available to read
requires java.base; // still required
}
requires
Modüllerin birbirlerine nasıl bağımlı olduklarına dair çözüm sürecini açıklar.
Bir 'talep' direktifi ('geçişi' ne olursa olsun) bunu ifade eder. bir modül başka bir modüle bağlıdır. Etkisi 'geçişli' değiştirici, ek modüllerin de bağlı olmasına neden olmaktır diğer modül. Eğer M 'modülü geçişli N' gerektiriyorsa, o zaman sadece M N'ye bağlıdır, ancak M'ye bağlı herhangi bir modül de bağlıdır. N. Bu, M'nin içeriğinin bir kısmı veya tamamı için yeniden onaylanmasını sağlar. bir modülü olan modülleri kesmeden yeni bir modül N'ye taşınabilir 'M' yönergesini gerektirir.
Kısacası :
requires
- M modülü diğer N modülüne bağlıdır.
requires transitive
- Ek modüller örtülü olarak diğer modüle bağlıdır. Örneğin: Eğer M modülü N'ye bağlıdır ve diğer P modülü M'ye bağlıdır. O zaman, dolaylı olarak N'ye de bağlıdır.
Nicolai ayrıntılı bir şekilde açıkladı. Burada sadece JDK kodundan belirli bir örnek veriyorum. Jdk.scripting.nashorn modülünü düşünün. Bu modülün modül bilgisi aşağıdaki gibidir:
Bu çizgiye sahip:
requires transitive java.scripting;
Bunun nedeni ise jdk.scripting.nashorn modülün kendi API'sı jdk.scripting.api.scripting paket kabul eder / türlerini döndürür javax.script paketinin java.scripting modülü. Jdk.scripting.nashorn, JMPS'ye jdk.scripting.nashorn'a bağlı herhangi bir modülün otomatik olarak java.scripting modülüne bağlı olduğunu söyler!
Şimdi, aynı jdk.scripting.nashorn modülü bu satırı kullanır:
requires jdk.dynalink;
başka bir modül için jdk.dynalink. Çünkü bu Yok jdk.scripting.nashorn modülünden dışa aktarılan paketlerin ("API"), jdk.dynalink modülünden türlerini kullanır. Jdk.scripting.nashorn tarafından jdk.dynalink kullanımı tamamen bir uygulama detayıdır.
Java 9 için Java Dil Özellikleri, bunu çok basit bir şekilde açıklar. Bölümünden Modül Bağımlılıkları:
requires
Yönerge, geçerli modülün bağımlı olduğu bir modülün adını belirtir....
requires
anahtar kelime değiştirici tarafından takip edilebilirtransitive
. Bu, herhangi bir modüle neden olurrequires
mevcut modülün, belirtilen modülde örtülü olarak bağımlı bir bağımlılığa sahip olmasırequires transitive
direktif.
Diğer bir deyişle:
requires
Y modülürequires transitive
modül Z,requires
modül Z.Dönem ulaşılabilirlik belirsizdir: türlerine erişmeden nesnelere erişebilirsiniz. Bir nesne, dışa aktarılmayan bir pakette bulunan T türündeyse ve "dışa aktarılmış" bir kod, bir T döndüren bir yönteme sahipse ... Bu yöntemi çağırırken, bu T nesnesinde bir tanıtıcı alırsınız (ve şunları yapabilirsiniz: kodunuzda bilinen herhangi bir türle ilgili herhangi bir yöntemi çağırınız).
okunabilirliğiayrıca belirsizdir: ClassLoader'ınızın her zaman (kaydedilmemiş) T sınıfını yükleyemeyeceği anlamına gelmez.