Marker Interface (İşaretleyici Arayüz)
Marker (işaretleyici) interface, içinde hiç metot olmayan bir arayüzdür. Tuhaf görünür — metot yoksa ne işe yarar? Amacı bir sınıfa etiket koymaktır: "bu tip şu yeteneğe/izne sahiptir". Derleyici veya çalışma zamanı b…
Marker Interface (İşaretleyici Arayüz)
Marker (işaretleyici) interface, içinde hiç metot olmayan bir arayüzdür. Tuhaf görünür —
metot yoksa ne işe yarar? Amacı bir sınıfa etiket koymaktır: "bu tip şu yeteneğe/izne sahiptir".
Derleyici veya çalışma zamanı bu etikete bakarak davranış değiştirir. Java'nın en ünlü
örneklerinden biri Serializable'dır (topic 68): metodu yoktur ama "bu sınıf serileştirilebilir"
der.
Nasıl çalışır?
interface Arsivlenebilir {} // metot yok — sadece etiket record Fatura(String no) implements Arsivlenebilir {} void arsivle(Object o) { if (o instanceof Arsivlenebilir) { /* arşivle */ } // etiket kontrolü else { /* reddet */ } }
Kod, instanceof ile "bu nesne işaretli mi?" diye sorar ve ona göre davranır. Örnek 1
(./Ornek1.java) bir Arsivlenebilir etiketi tanımlar; arşiv servisi yalnızca işaretli nesneleri
kabul eder.
JDK'daki yerleşik marker interface'ler:
Serializable:ObjectOutputStreambunu arar; yoksaNotSerializableException.Cloneable:Object.clone()bunu arar; yoksaCloneNotSupportedException.RandomAccess: "Bu liste hızlı indeksli erişim sunar" (ArrayList evet, LinkedList hayır); algoritmalar buna göre strateji seçer.
Marker interface vs marker annotation
Modern Java'da aynı "etiketleme" işi genelde anotasyonla yapılır (@Entity, @Component,
@Test). İkisini karşılaştıralım:
| Marker interface | Marker annotation | |
|---|---|---|
| Tip güvenliği | Var (derleyici zorlar) | Yok (çalışma zamanı) |
| Kontrol | instanceof (hızlı) | reflection (isAnnotationPresent) |
| Esneklik | Yalnızca tipe | Tip/metot/alan/parametre |
| Meta-veri | Taşıyamaz | Taşıyabilir (alanlar) |
| Kalıtım | Alt tiplere geçer; tek-kalıtıma dahil | Bağımsız |
Örnek 2 (./Ornek2.java) aynı etiketi bir anotasyonla yapar ve reflection ile kontrol eder.
Ne zaman hangisi?
- Marker interface: Etiketli tiplerin yalnızca belirli metotlara parametre olmasını derleme
zamanında zorlamak istiyorsan (tip güvenliği). Örn.
void kaydet(Serializable s). - Marker annotation: Esneklik, meta-veri (
@Column(name="...")gibi) veya metot/alan işaretleme gerekiyorsa. Modern framework'ler (Spring, JPA, JUnit) bu yolu kullanır.
Joshua Bloch (Effective Java): "Eğer işaretlenen şey yalnızca bir tipse ve onu bir metoda parametre olarak kısıtlamak istiyorsan marker interface; aksi halde annotation tercih et."
Özet
Marker interface'in metotsuz bir etiket olduğunu; instanceof ile kontrol edilip davranış
değiştirdiğini ve Serializable/Cloneable/RandomAccess gibi yerleşik örneklerini (Örnek 1);
marker annotation alternatifini, ikisinin tip-güvenliği/esneklik karşılaştırmasını ve ne zaman
hangisinin seçileceğini (Örnek 2) öğrendik. Sırada, en çok kullanılan yerleşik anotasyon ve
arkadaşları: @Deprecated ve anotasyonlar.
▶ Kod Örnekleri(2)
Ornek1
çalıştırılabilir1// Ornek1: Marker (işaretleyici) interface — metodu olmayan, sınıfı "etiketleyen" arayüz.
2// Çalıştırma: java Ornek1.java
3import java.util.List;
4
5public class Ornek1 {
6
7 // Marker interface: METODU YOK. Amacı, bir sınıfa "yetenek/izin" etiketi koymaktır.
8 interface Arsivlenebilir {} // "bu nesne arşivlenebilir" etiketi
9
10 record Fatura(String no) implements Arsivlenebilir {}
11 record Log(String mesaj) implements Arsivlenebilir {}
12 record GeciciDosya(String ad) {} // arşivlenemez (etiket yok)
13
14 // Arşiv servisi: yalnızca işaretli (Arsivlenebilir) nesneleri kabul eder.
15 static void arsivle(Object nesne) {
16 if (nesne instanceof Arsivlenebilir) { // etiket KONTROLÜ
17 System.out.println(" arşivlendi: " + nesne);
18 } else {
19 System.out.println(" REDDEDİLDİ (Arsivlenebilir değil): " + nesne);
20 }
21 }
22
23 public static void main(String[] args) {
24 List<Object> nesneler = List.of(
25 new Fatura("F-100"), new Log("giriş yapıldı"), new GeciciDosya("temp.tmp"));
26 for (Object n : nesneler) arsivle(n);
27
28 System.out.println("""
29
30 --- Marker (işaretleyici) interface ---
31 Metodu olmayan, yalnızca bir sınıfı "işaretleyen/etiketleyen" arayüzdür.
32 instanceof ile kontrol edilir: "bu nesne şu yeteneğe/izne sahip mi?"
33 JDK örnekleri: Serializable (serileştirilebilir), Cloneable (klonlanabilir), RandomAccess (hızlı indeks).
34 Derleyici/çalışma zamanı bu etikete göre davranış değiştirir (örn. ObjectOutputStream Serializable arar).""");
35 }
36}Ornek2
çalıştırılabilir1// Ornek2: Marker interface vs marker ANNOTATION (modern alternatif).
2// Çalıştırma: java Ornek2.java
3import java.lang.annotation.Retention;
4import java.lang.annotation.RetentionPolicy;
5
6public class Ornek2 {
7
8 // Modern alternatif: işaretlemeyi bir ANOTASYONLA yapmak.
9 @Retention(RetentionPolicy.RUNTIME) // çalışma zamanında okunabilsin
10 @interface Denetlenebilir {}
11
12 @Denetlenebilir
13 static class OdemeServisi {}
14 static class YardimServisi {} // işaretsiz
15
16 public static void main(String[] args) {
17 // Anotasyon etiketi reflection ile kontrol edilir (interface'te instanceof'un karşılığı).
18 kontrol(new OdemeServisi());
19 kontrol(new YardimServisi());
20
21 System.out.println("""
22
23 --- Marker interface vs marker annotation ---
24 İkisi de "etiketleme" yapar; farkları:
25 MARKER INTERFACE:
26 + tip güvenliği: yalnızca işaretli tipler bir metoda parametre olabilir (derleyici zorlar).
27 + instanceof ile hızlı kontrol.
28 - bir kez işaretlenince alt tiplere de geçer; esnek değil; tek kalıtım kısıtına dahil.
29 MARKER ANNOTATION:
30 + daha esnek: metot/alan/parametreye de uygulanabilir; meta-veri (alanlar) taşıyabilir.
31 + tipe bağlı değil; reflection ile okunur.
32 - derleme-zamanı tip güvenliği YOK; kontrol çalışma zamanında yapılır.
33 Modern Java/Spring çoğunlukla ANOTASYON kullanır (@Entity, @Component...). Yine de
34 Serializable gibi yerleşik marker interface'ler hâlâ yaygındır.""");
35 }
36
37 static void kontrol(Object nesne) {
38 boolean isaretli = nesne.getClass().isAnnotationPresent(Denetlenebilir.class);
39 System.out.println(" " + nesne.getClass().getSimpleName()
40 + " denetlenebilir mi? " + isaretli);
41 }
42}