Java’da Yıldız Savaşları! Wildcard kullanımı import a.* vs import a.X

Arif Acar
3 min readJan 7, 2021

--

Geçtiğimiz günlerde çok tecrübeli bir ekip arkadaşımla yine pair programming yaparken Java’daki bu import’ların yıldız(*) karakteri (joker ya da wildcard olarakta adlandırılıyor) ile mi yoksa tek tek yapılması mı gerektiği konusunda biraz kafa yorduk. Daha önce de farklı yerlerde karşıma çıkan bu konuya bir açıklık getirmeye çalıştım.

Ctrl + Shift + O ya da Option + Cmd + O tutkunları da geldiyse hemen başlayalım :)

Öncelikle bilmelisiniz ki wildcard kullanalım ya da kullanmayalım uygulamanın çalışma anında performansa hiçbir etkisi yok. Çünkü derleme sonrasında derleyici bize birebir aynı byte kodunu üretir. Ancak derleme süresi olarak ms düzeyinde dikkate değer alınmayacak bir yavaşlamaya sebep olur. Çünkü derleyici kodda kullanılan sınıflara ulaşmak için paket altındaki tüm sınıfları tek tek tarar.

2008 yılında Stackoverflow üzerinden bu konu tartışmaya açılmış ve çok farklı yaklaşımların olduğunu gördük. Soruyu soran arkadaşın cevabını kabul ettiği ve çok fazla oy alan cevaba baktığınızda bu import’ların tek tek yapılması yönünde. Farklı paketlerde aynı isme sahip sınıflarda sorun çıkarabileceğini gösterilmiş. Aynı isimdeki sınıfların varlığı uygulamamızın derlenmesini önleyecektir . Aynı isimde sınıflardan birini yanlış import etmeye elverişli olduğundan kimi zaman o sınıfı kullandığımız yerdeki hatanın farkına varamayabiliyoruz. Bir diğer görüş de tüm sınıfların açıkça import etmenin avantajı, hangi sınıfı kullanmak istediğinizi bir bakışta anlayabilmektir. Bu da kodu daha okunaklı olduğunu savunuluyor.

Şahsen wilcard kullanmaya daha eğilimli biri olduğumu söyleyebilirim. Bir pakette çok sayıda sınıf var ise wildcard kullanmak bazen daha temiz görünüm sağlayabilir. Bunu kullandığım IDE’de sayesinde yönetebiliyorum. Aaşağıdaki örnekte de görüleceği gibi bir pakatte 5'ten fazla sınıf varsa wildcard kullanılsın istedim.

Intellij IDEA için default olarak 5 gelmektedir

Conflict olabilecek sınıflar için de basit çözüm var. Aşağıdaki örnekte hem sql’e ait hem de util’e ait iki ayrı Date sınıfı yer alıyor. Her ikisini de wildcard kullandığımızda sonradan yaptığımız import işlemi bir öncekilerini ezecek. Böylece uygulamaya sql’in Date sınıfını kullanacağını belirtmiş oluyoruz.

import java.sql.*;
import java.util.*;
import java.sql.Date;

Yukarıdaki gibi çok fazla sayıda sonradan import etmemiz gereken sınıflar varsa bunu uygulamak yine zaman kaybına sebep olacaktır. Bu durumda da wilcard kullanımından kaçmak daha doğru olacaktır.

Modern IDE’ler bu import’ları import... gibi çeşitli yöntemlerle gizlese de kodu okumak ve yazmak için her zaman bir IDE’ye bağımlı olmayabiliriz. Tabi IDE kullanılmaması da ayrı bir tartışma konusu. Bu argümanı savunanlar kendilerine hayatı neden bu kadar zorlaştırmaya çalıştıklarını da anlamak en azından benim için zor.

Bu arada Bob amca da Clean Code kitabında anlattığım benzer kaygılardan dolayı wildcard kullanımını önermiş.

Sonarqube ya da IDE’lere plugin olarak yüklenen SonarLint gibi araçlar kullanıyosanız da wildcard’ların kullanılması kritik bir code smell olarak belirtilmiş. Static import’lar konunun dışında tutulmuş. Bir paketin tüm sınıflarını wildcard ile körü körüne içe aktarmak aynı isme sahip farklı paketlerdeki sınıflar arasında çakışmalara ve sürüm yönetimi konusunda bazı karışıklıklara sebep olabileceği belirtilmiş.

Google’ın yayınladığı “Google Java Style Guide” içerisinde de wildcard kullanımından kaçınılması önerilmiş.

Sonuç

Sonuç olarak performans kaybı yok, derleme süresi çok az miktarda artıyor ama hangi yöntemin daha clean olduğu tartışmaya açık. Burada tam bir doğru ya da yanlış yoktur. Bu tarz tartışmaya açık ve net olarak bir doğrusu olmayan konuları ekip arkadaşlarınızla uzun uzun tartışıp zaman kaybetmeyin. Kullanacağınız yöntemi daha demokratik bir yöntemle de belirleyebilirsiniz.

Yazı içerisindeki altı çizili kelimelere ilgili konunun kaynağını link olarak ekledim.

İyi kodlamalar :)

--

--