Paketler (Packages)
Bir proje büyüdükçe yüzlerce, binlerce sınıf olur. Bunları tek bir klasöre yığmak hem kaosa yol açar hem de isim çakışmalarına (iki farklı Date sınıfı gibi) neden olur. Paketler, sınıfları mantıksal gruplara ayıran ve…
Paketler (Packages)
Bir proje büyüdükçe yüzlerce, binlerce sınıf olur. Bunları tek bir klasöre yığmak hem kaosa yol
açar hem de isim çakışmalarına (iki farklı Date sınıfı gibi) neden olur. Paketler, sınıfları
mantıksal gruplara ayıran ve her birine benzersiz bir isim alanı (namespace) veren mekanizmadır.
Java'nın kendi kütüphanesi de paketlerle düzenlenmiştir: java.util, java.io, java.net...
Paket nedir?
Paket, ilişkili sınıfları bir araya getiren isimlendirilmiş bir gruptur. Bir sınıfın paketini,
dosyanın başındaki package bildirimi belirler ve bu, klasör yapısıyla eşleşir:
package com.egitim.uygulama.servis; // dosya: com/egitim/uygulama/servis/SiparisServisi.java public class SiparisServisi { ... }
Bir sınıfın tam nitelikli adı (fully-qualified name, FQN) = paket + sınıf adı:
com.egitim.uygulama.servis.SiparisServisi.
İsimlendirme geleneği: Paket adları, çakışmayı önlemek için kurumun ters domain'iyle başlar:
com.sirket.proje.modul. Hepsi küçük harftir.
Not: Bu portalın örnekleri tek dosyada (default pakette) çalışır; bu yüzden kendi paketlerimizi oluşturmak yerine, JDK'nin paketlerini (java.util, java.math...) kullanarak import ve FQN kavramlarını gösteriyoruz.
import: kısa adla kullanım
Başka bir paketteki sınıfı kullanmak için ya tam adını yazarsın ya da import ile kısa adını
getirirsin:
import java.util.List; // tek sınıf import java.util.*; // paketteki tüm sınıflar (yıldız) List<String> liste = ...; // artık kısa adla
java.lang paketi (String, System, Math, Integer...) otomatik içe aktarılır; onları import
etmen gerekmez. Örnek 1 (./Ornek1.java) import'u, tam nitelikli adı ve bir isim çakışmasının
(java.util.Date vs java.sql.Date) FQN ile nasıl çözüldüğünü gösterir.
static import
Normal import bir sınıfı getirir; static import ise bir sınıfın statik üyelerini
(alan/metot) doğrudan kullanmanı sağlar:
import static java.lang.Math.PI; import static java.lang.Math.sqrt; double alan = PI * sqrt(r); // Math.PI / Math.sqrt yerine
Matematik ağırlıklı kod ve testlerde (assertEquals) okunabilirliği artırır. Örnek 2
(./Ornek2.java) Math ve Collectors'tan static import gösterir. Aşırı kullanım "bu metot
nereden geliyor?" karışıklığı yarattığından ölçülü kullanılmalıdır.
Paket-özel erişim ve düzen
Erişim belirleyiciler bölümünde gördüğümüz default (paket-özel) erişim, paketlerle birlikte anlam kazanır: belirleyici yazılmayan üyeler yalnızca aynı paketten erişilir. Bu, bir paketin "iç" sınıflarını dışarıya kapatmak için kullanılır.
package-info.java adlı özel bir dosya ile bir pakete dokümantasyon ve paket düzeyi anotasyonlar
eklenebilir.
Derleme, classpath ve JAR
- Paketler, derlenmiş
.classdosyalarının klasör yapısına yansır (com/egitim/...). - CLASSPATH, JVM'in sınıfları nerede arayacağını söyler.
- Bir kütüphane, paketler hâlinde düzenlenmiş sınıfların bir JAR dosyasında paketlenmiş halidir (Build araçları bölümünde gördük).
- Modül sistemi (JPMS, Java 9+), paketlerin üstünde bir katman daha ekler: hangi paketlerin
dışa açılacağını (
exports)module-info.javaile belirtirsin (ileri konu).
Özet
Paketlerin sınıfları nasıl gruplayıp isim çakışmalarını önlediğini; package bildirimini ve FQN'i;
import ile kısa kullanımı ve isim çakışması çözümünü (Örnek 1); static import'u (Örnek 2);
paket-özel erişimi, classpath ve JAR ilişkisini öğrendik. Düzenli paket yapısı, büyük projeleri
yönetilebilir kılar. Sırada, nesneler arası "sahip olma" (HAS-A) ilişkisi: aggregation ve
composition.
▶ Kod Örnekleri(2)
Ornek1
çalıştırılabilir1// Ornek1: import, tam nitelikli ad (FQN) ve isim çakışması çözümü.
2// Paketler, sınıfları gruplar ve isim çakışmalarını önler.
3// Çalıştırma: java Ornek1.java
4import java.util.ArrayList; // java.util paketinden ArrayList'i içe aktar
5import java.util.List;
6import java.util.Date; // java.util.Date'i içe aktardık
7
8public class Ornek1 {
9
10 public static void main(String[] args) {
11 // import sayesinde kısa adla kullanırız:
12 List<String> liste = new ArrayList<>();
13 liste.add("paket");
14 liste.add("import");
15 System.out.println("java.util.List: " + liste);
16
17 // import edilmiş java.util.Date kısa adla:
18 Date utilTarih = new Date(0L);
19 System.out.println("java.util.Date: " + utilTarih.toInstant());
20
21 // İSİM ÇAKIŞMASI: java.sql.Date de var. İkisini aynı anda kısa adla kullanamayız;
22 // birini TAM NİTELİKLİ AD (fully-qualified name) ile yazarız.
23 java.sql.Date sqlTarih = new java.sql.Date(0L);
24 System.out.println("java.sql.Date : " + sqlTarih);
25
26 // Hiç import etmeden de tam adla kullanılabilir (uzun ama net):
27 java.math.BigDecimal para = new java.math.BigDecimal("19.99");
28 System.out.println("java.math.BigDecimal: " + para);
29
30 System.out.println("""
31
32 --- Paketler ve import ---
33 Paket = sınıfları gruplayan bir isim alanı (namespace), örn. java.util, com.egitim.app.
34 import: bir sınıfı kısa adıyla kullanmayı sağlar (java.util.List -> List).
35 Tam nitelikli ad (FQN): paket + sınıf (java.sql.Date). İsim çakışmasını çözer.
36 java.lang paketi (String, System, Math...) otomatik içe aktarılır; import gerekmez.""");
37 }
38}Ornek2
çalıştırılabilir1// Ornek2: static import — bir sınıfın statik üyelerini kısa adla kullanmak.
2// Çalıştırma: java Ornek2.java
3import static java.lang.Math.PI;
4import static java.lang.Math.sqrt;
5import static java.lang.Math.pow;
6import static java.util.stream.Collectors.toList;
7
8import java.util.List;
9import java.util.stream.Stream;
10
11public class Ornek2 {
12
13 public static void main(String[] args) {
14 // static import sayesinde Math.PI / Math.sqrt yerine doğrudan PI / sqrt yazarız.
15 double yaricap = 3;
16 System.out.println("Daire alanı (PI * r^2): " + (PI * pow(yaricap, 2)));
17 System.out.println("Karekök 144 : " + sqrt(144));
18
19 // Collectors.toList -> toList (static import)
20 List<Integer> kareler = Stream.of(1, 2, 3, 4).map(n -> n * n).collect(toList());
21 System.out.println("Kareler: " + kareler);
22
23 System.out.println("""
24
25 --- static import ---
26 Normal import: bir SINIFI içe aktarır (Math).
27 static import: bir sınıfın STATİK üyelerini (PI, sqrt) doğrudan kullanmayı sağlar.
28 Faydası: matematik/yardımcı/test (assertEquals) kodunda okunabilirlik.
29 Dikkat: aşırı kullanım kafa karıştırır (bu metot nereden geliyor?); ölçülü kullan.""");
30 }
31}