Yanıtlar:
Bununla ilgili tek sorun, yerel ad alanınızı tıkamasıdır. Örneğin, bir Swing uygulaması yazdığınızı java.awt.Event
ve buna ihtiyaç duyduğunuzu ve şirketin sahip olduğu takvim sistemi ile de arayüz oluşturduğunuzu varsayalım com.mycompany.calendar.Event
. Her ikisini de joker karakter yöntemini kullanarak içe aktarırsanız, şu üç şeyden biri gerçekleşir:
java.awt.Event
ve com.mycompany.calendar.Event
hatta derlemek olamaz ve bu yüzden..*
), ancak bu yanlıştır ve kodunuzun neden türün yanlış olduğunu iddia ettiğini anlamakta zorlanırsınız.com.mycompany.calendar.Event
, ancak daha sonra bir tane eklediklerinde, daha önce geçerli olan kodunuz derlenmeyi durdurur.Tüm ithalatları açıkça listelemenin avantajı, bir bakışta hangi sınıfı kullanmak istediğinizi söyleyebilmemdir, bu da kodu okumayı çok daha kolay hale getirir. Sadece hızlı bir kerelik bir şey yapıyorsanız, açıkça yanlış bir şey yoktur , ancak gelecekteki koruyucular aksi takdirde netliğiniz için size teşekkür edecektir.
Yıldız ithalatı için bir oy . İçe aktarma ifadesi, bir sınıfı değil, bir paketi içe aktarmayı amaçlamaktadır . Tüm paketleri almak çok daha temiz; burada tanımlanan sorunlar (örn. java.sql.Date
vs java.util.Date
) diğer yollarla kolayca çözülür, gerçekte değil belirli ithalatlarla ele ve kesinlikle tüm sınıflardaki delice bilgiçlikle ithalatı haklı çıkarmaz. Bir kaynak dosyasını açmaktan ve 100 içe aktarma ifadesini kullanmak zorunda kalmaktan daha rahatsız edici bir şey yoktur.
Belirli ithalatlar yapmak, yeniden düzenlemeyi zorlaştırır; bir sınıfı kaldırır / yeniden adlandırırsanız, sınıfın tüm içe aktarmalarını kaldırmanız gerekir . Bir uygulamayı aynı paketteki farklı bir sınıfa geçirirseniz, içe aktarmaları düzeltmeniz gerekir. Bu ekstra adımlar otomatikleştirilebilse de, gerçek bir kazanç elde etmek için gerçekten verimlilik vuruşlarıdır.
Eclipse varsayılan olarak sınıf ithalatı yapmasa bile, herkes yine de yıldız ithalatı yapıyordu. Üzgünüm, ama belirli ithalatlar yapmak için gerçekten mantıklı bir gerekçe yok.
Sınıf çatışmalarıyla nasıl başa çıkacağınız aşağıda açıklanmıştır:
import java.sql.*;
import java.util.*;
import java.sql.Date;
Foo
ve kodunuzu IDE kullanmadan okursam (argümanınız bir tane kullanmak zorunda olmamam gerektiğinden), hangi paketin Foo
geldiğini nasıl bileceğim ? Elbette, bir IDE kullanarak IDE bana söyleyecektir, ancak tüm argümanınız kodu bir tane olmadan okuyabilmem gerektiğidir . Açık ithalat yardım yapmak belgeyi kodu (önlemek joker karakterler büyük nedeni) ve ben olacağım daha olasıdır çok var okuma ben olacağım bunun dışında bir IDE kullanmadan kod yazma bir IDE kullanmadan kod.
lütfen makaleme bakın Talep Üzerine İthalat Kötülük
Kısacası, en büyük sorun, içe aktardığınız pakete bir sınıf eklendiğinde kodunuzun kırılabilmesidir . Örneğin:
import java.awt.*;
import java.util.*;
// ...
List list;
Java 1.1'de bu iyiydi; Java.awt dosyasında liste bulundu ve çakışma olmadı.
Şimdi, mükemmel çalışan kodunuzu kontrol ettiğinizi ve bir yıl sonra bir başkası bunu düzenlemek için çıkardığını ve Java 1.2 kullandığını varsayalım.
Java 1.2, java.util dosyasına List adlı bir arabirim ekledi. BOOM! Fikir ayrılığı. Mükemmel çalışan kod artık çalışmıyor.
Bu bir EVIL dil özelliğidir. Orada YOK kod türü sırf derleme durdurmak gerektiğini sebebi eklenen bir pakete ...
Ayrıca, bir okuyucunun hangi "Foo" kullandığınızı belirlemesini zorlaştırır.
java.util.List
vs java.awt.List
anlamak çok kötü değil, ama sınıf adı Configuration
ve birden fazla bağımlılık kütüphaneleri en son maven repo sürümü ekledikçe deneyin .
Bu var olmayan bir Java ithalat ifadesiyle vahşi kartı kullanmak için kötü.
Gelen Temiz Kanunu , Robert C. Martin aslında uzun ithalat listeleri önlemek için bunları kullanılmasını önerir.
İşte tavsiye:
J1: Joker Karakter Kullanarak Uzun Alma Listelerinden Kaçının
Bir paketten iki veya daha fazla sınıf kullanıyorsanız, paketin tamamını
ithalat paketi. *;
Uzun ithalat listeleri okuyucu için göz korkutucu. Modüllerimizin tepelerini 80 satırlık ithalatla karıştırmak istemiyoruz. Bunun yerine, ithalatın hangi paketlerle işbirliği yaptığımız konusunda kısa ve öz bir ifade olmasını istiyoruz.
Spesifik ithalatlar zor bağımlılıklardır, ancak joker karakterli ithalatlar değildir. Bir sınıfı özellikle içe aktarıyorsanız, o sınıfın bulunması gerekir. Ancak, joker karakter içeren bir paketi içe aktarırsanız, belirli sınıfların bulunması gerekmez. İçe aktarma ifadesi, isimleri araştırırken paketi arama yoluna ekler. Bu nedenle, bu tür ithalatlar tarafından gerçek bir bağımlılık yaratılmaz ve bu nedenle modüllerimizi daha az bağlı tutarlar.
Belirli ithalatların uzun listesinin yararlı olabileceği zamanlar vardır. Örneğin, eski kodla uğraşıyorsanız ve hangi sınıfları taklit etmek ve saplama yapmak istediğinizi bulmak istiyorsanız, tüm bu sınıfların gerçek nitelikli adlarını bulmak için belirli ithalatların listesini yürütebilir ve daha sonra uygun taslakları yerleştirin. Bununla birlikte, belirli ithalatlar için bu kullanım çok nadirdir. Ayrıca, çoğu modern IDE, joker karakterli içe aktarmaları tek bir komutla belirli bir içe aktarma listesine dönüştürmenize izin verecektir. Bu yüzden eski durumda bile joker karakterler almak daha iyidir.
Joker karakterle içe aktarma bazen ad çakışmaları ve belirsizliklere neden olabilir. Aynı ada sahip ancak farklı paketlerde iki sınıfın özel olarak içe aktarılması veya kullanıldığında en azından özel olarak kalifiye olması gerekir. Bu bir sıkıntı olabilir, ancak joker karakterli ithalat kullanmanın hala belirli ithalatlardan daha iyi olacağı kadar nadirdir.
Performans : Bayt kodu aynı olduğundan performans üzerinde hiçbir etkisi yoktur. ancak bazı ek yüklere yol açacaktır.
Derleme : kişisel makinemde, hiçbir şey içe aktarmadan boş bir sınıf derlemek 100 ms sürer, ancak içe aktarma java sırasında aynı sınıf.
import java.*
hiçbir şey ithal etmez. Neden bir fark yaratsın ki?
Belirsiz olan tüm sınıf adlarını tam olarak belirtmenizi gerektiren ad alanınızı karmaşık hale getirir. Bunun en yaygın oluşumu:
import java.util.*;
import java.awt.*;
...
List blah; // Ambiguous, needs to be qualified.
Ayrıca, tüm bağımlılıklarınız dosyanın üstünde listelendiği için bağımlılıklarınızı somut hale getirmenize yardımcı olur.
Önemli miktarda Java kullanan çalıştığım çoğu yer, açık içe aktarmaları kodlama standardının bir parçası haline getiriyor. Bazen hızlı prototipleme için * kullanıyorum ve daha sonra kodu üretirken içe aktarma listelerini (bazı IDE'ler de sizin için yapacak) genişletiyorum.
Önceki bir projede, * ithalatlarından belirli ithalatlara geçişin derleme süresini yarı yarıya azalttığını (yaklaşık 10 dakikadan yaklaşık 5 dakikaya) buldum. * -İmport, derleyicinin, kullandığınız sınıfla eşleşen bir sınıf için listelenen paketlerin her birinde arama yapmasını sağlar. Bu süre küçük olsa da, büyük projelere katkıda bulunur.
* -İmport'un bir yan etkisi, geliştiricilerin ihtiyaç duydukları şeyleri düşünmek yerine ortak ithalat hatlarını kopyalayıp yapıştırmalarıydı.
In DDD kitapta
Uygulama hangi temeli temel alacak olursa, MODÜLLERİ yeniden düzenleme çalışmalarını en aza indirmenin yollarını arayın. Java'da, ayrı ayrı sınıflara içe aktarmadan kaçış yoktur, ancak en azından bir seferde tüm paketleri içe aktarabilirsiniz, bu da paket adlarının oldukça uyumlu birimler olma niyetini yansıtırken aynı zamanda paket adlarını değiştirme çabasını da azaltır.
Ve yerel ad alanını tıkarsa, bu sizin hatanız değil - paketin boyutunu suçlayın.
Derleyici otomatik olarak * somut sınıf adlarıyla değiştirildiği için çalışma zamanı etkisi yoktur. Eğer .class dosyasını kodalıyorsanız, asla göremezsiniz import ...*
.
C # her zaman yalnızca using
paket adını kullanabileceğiniz gibi * (örtük olarak) kullanır . Sınıf adını asla belirtemezsiniz. Java özelliği c # 'dan sonra tanıtır. (Java birçok açıdan zor ama bu konunun ötesinde).
Intellij Idea'da "içe aktarma düzenleme" yaptığınızda, aynı paketin çoklu içe aktarmalarını * ile otomatik olarak değiştirir. Bu, zorunlu bir özelliktir, çünkü kapatamazsınız (eşiği artırabilirsiniz).
Kabul edilen cevapta listelenen vaka geçerli değil. * Olmadan hala aynı sorunu yaşarsınız. * Kullansanız da kullanmasanız da, kodunuzda pakcage adını belirtmeniz gerekir.
Kayıt için: Bir içe aktarma eklediğinizde, bağımlılıklarınızı da belirtirsiniz.
Dosyaların bağımlılıklarının ne olduğunu hızlı bir şekilde görebilirsiniz (aynı ad alanının sınıfları hariç).
En önemlisi, içe aktarmanın java.awt.*
programınızı gelecekteki bir Java sürümüyle uyumsuz hale getirebilmesidir:
"ABC" adlı bir sınıfınız olduğunu, JDK 8 kullandığınızı ve içe aktardığınızı varsayalım java.util.*
. Şimdi, Java 9'un ortaya çıktığını ve java.util
tesadüfen "ABC" olarak da adlandırılan yeni bir sınıfı olduğunu varsayalım . Programınız şimdi Java 9'da derlenmeyecektir, çünkü derleyici "ABC" adıyla kendi sınıfınızı veya yeni sınıfınızıjava.awt
.
Yalnızca java.awt
gerçekten kullandığınız sınıfları açıkça içe aktardığınızda bu sorunla karşılaşmazsınız .
Kaynaklar:
Stream
Java 8'de Java'da java.util'de eklenen yeni bir sınıf örneği olarak kullanabilirsiniz ...
Her iki tarafta yapılan tüm geçerli noktalar arasında, joker karakterden kaçınmak için ana nedenimi bulamadım: Kodu okuyabilmeyi ve her sınıfın ne olduğunu veya tanımın dilde olmadığını veya dosya, nerede bulunur. Birden fazla paket * ile içe aktarılırsa, tanımadığım bir sınıfı bulmak için her birini aramaya gitmem gerekiyor. Okunabilirlik en üst düzeydedir ve kodu okumak için bir IDE gerektirmemelidir .