Eğitim Portalı/Java/@Deprecated ve Anotasyonlar
Java01-java/81-deprecated-ve-anotasyonlar

@Deprecated ve Anotasyonlar

Anotasyonlar (annotations), koda meta-veri ekler: @Override, @Deprecated, @Entity, @Test... Kodun davranışını doğrudan değiştirmezler ama derleyici, araçlar ve framework'ler bunları okuyup ona göre davranır. Reflectio…

@Deprecated ve Anotasyonlar

Anotasyonlar (annotations), koda meta-veri ekler: @Override, @Deprecated, @Entity, @Test... Kodun davranışını doğrudan değiştirmezler ama derleyici, araçlar ve framework'ler bunları okuyup ona göre davranır. Reflection bölümünde (topic 16) kendi anotasyonunu tanımlamayı gördük; burada Java'nın yerleşik anotasyonlarına ve özellikle @Deprecated'a odaklanıyoruz.

@Override

Bir metodun üst tipteki bir metodu ezdiğini (override) belirtir. Zorunlu değildir ama kullanmalısın: metot imzasını yanlış yazarsan (override yerine yeni metot oluşturursan) derleyici hata verir — sessiz bir hatayı yakalar:

@Override public String selam() { ... }   // imza üst tiple uyuşmazsa derleme hatası

@Deprecated

"Bu öğeyi artık kullanma, daha iyisi var" der. Java 9'dan beri iki yararlı alan taşır:

@Deprecated(since = "2.0", forRemoval = true)
public int hesaplaEski(int x) { ... }
  • since: Hangi sürümden beri kullanımdan kaldırıldı.
  • forRemoval = true: Gelecekte silinecek (sadece "önerilmiyor" değil; geçişi planla).

Deprecated bir öğeyi çağıran kod derlenir ama derleyici uyarı verir; IDE'ler üstü çizili gösterir. Kütüphane evriminde, eski API'leri kırmadan kullanıcıları yeniye yönlendirmenin standart yoludur. Örnek 1 (./Ornek1.java) @Override, @Deprecated ve @SuppressWarnings'i gösterir.

@SuppressWarnings

Belirli derleyici uyarılarını bilinçli olarak bastırır: @SuppressWarnings("deprecation"), @SuppressWarnings("unchecked"). Dikkatli kullan — uyarı çoğu zaman gerçek bir sorunu işaret eder; yalnızca bilerek ve kapsamı dar tutarak bastır.

@FunctionalInterface ve @SafeVarargs

  • @FunctionalInterface: Bir arayüzün tek soyut metotlu kalmasını garanti eder (lambda hedefi). İkinci bir soyut metot eklersen derleme hatası verir — niyeti belgeler ve korur.
  • @SafeVarargs: Jenerik varargs metotlarındaki "unchecked / heap pollution" uyarısını, kodun güvenli olduğunu bildiğinde bastırır.

Örnek 2 (./Ornek2.java) bunları ve aşağıdaki meta-anotasyonları gösterir.

Meta-anotasyonlar (anotasyon tanımlarken)

Kendi anotasyonunu yazarken kullanılan anotasyonlar:

Meta-anotasyonNe belirler
@RetentionAnotasyon ne kadar yaşar: SOURCE / CLASS / RUNTIME (reflection için RUNTIME)
@TargetNereye uygulanabilir: TYPE, METHOD, FIELD, PARAMETER...
@InheritedAlt sınıflara miras geçer mi
@DocumentedJavadoc'a dahil edilsin mi
@RepeatableAynı yere birden çok kez uygulanabilir mi

Kendi anotasyonunu tanımlama ve reflection ile okuma (isAnnotationPresent, getAnnotation) ayrıntısı Reflection ve Annotations konusundadır (topic 16).

Anotasyonların gücü: framework'ler

Anotasyonlar modern Java'nın bel kemiğidir. Spring (@Component, @Autowired, @GetMapping), JPA (@Entity, @Column), JUnit (@Test) — hepsi anotasyon okuyup davranış üretir. Yani "yapılandırmayı koda gömme" felsefesinin aracıdır (bu portalın backend'i baştan sona anotasyonlarla yapılandırılmıştır).

Özet

Yerleşik anotasyonları öğrendik: imza güvenliği sağlayan @Override, kullanımdan kaldırmayı since/forRemoval ile bildiren @Deprecated, uyarı bastıran @SuppressWarnings (Örnek 1); lambda hedefini koruyan @FunctionalInterface, @SafeVarargs ve meta-anotasyonlar (Örnek 2); anotasyonların framework'lerdeki merkezi rolüne değindik. Sırada, JVM'in performansını şekillendiren iki mekanizma: Garbage Collection ve JIT.

Kod Örnekleri(2)

Ornek1

çalıştırılabilir
Ornek1.java
1// Ornek1: Yerleşik anotasyonlar — @Override, @Deprecated, @SuppressWarnings.
2// Çalıştırma: java Ornek1.java
3public class Ornek1 {
4
5    static class EskiApi {
6        // @Deprecated: "kullanma, daha iyisi var". since/forRemoval ile detaylandırılır.
7        @Deprecated(since = "2.0", forRemoval = true)
8        public int hesaplaEski(int x) { return x * 2; }
9
10        // Yeni, önerilen metot:
11        public int hesapla(int x) { return x * 2; }
12    }
13
14    static class Temel {
15        public String selam() { return "Temel selam"; }
16    }
17    static class Turetilmis extends Temel {
18        // @Override: bu metot üst sınıftakini EZİYOR (derleyici doğrular; imza yanlışsa hata verir).
19        @Override
20        public String selam() { return "Türetilmiş selam"; }
21    }
22
23    public static void main(String[] args) {
24        EskiApi api = new EskiApi();
25        // Deprecated metodu çağırmak DERLENİR ama derleyici UYARI verir (kullanmaman gerektiğini söyler).
26        System.out.println("eski (deprecated): " + api.hesaplaEski(5));
27        System.out.println("yeni (önerilen)  : " + api.hesapla(5));
28
29        System.out.println("override: " + new Turetilmis().selam());
30
31        // @SuppressWarnings: belirli derleyici uyarılarını bastırır (bilinçli kullan).
32        eskiKullan();
33
34        System.out.println("""
35
36                --- Yerleşik anotasyonlar ---
37                @Override: bir metodun üst tipi EZDİĞİNİ belirtir; imza uyuşmazsa derleyici HATA verir (güvenlik ağı).
38                @Deprecated(since, forRemoval): "artık kullanma". forRemoval=true -> gelecekte SİLİNECEK.
39                  Çağıran kod derlenir ama uyarı alır; IDE üstü çizili gösterir.
40                @SuppressWarnings(\"...\"): belirli uyarıları bastırır (deprecation, unchecked...). Dikkatli kullan.
41                Anotasyonlar koda META-VERİ ekler; derleyici, araçlar ve framework'ler bunları okur.""");
42    }
43
44    @SuppressWarnings("deprecation") // bilinçli olarak deprecated API çağrısının uyarısını bastır
45    static void eskiKullan() {
46        System.out.println("@SuppressWarnings ile: " + new EskiApi().hesaplaEski(10));
47    }
48}
Çıktı yerel JDK 21 ile yakalandı — tarayıcıda JVM çalışmaz.

Ornek2

çalıştırılabilir
Ornek2.java
1// Ornek2: @FunctionalInterface, @SafeVarargs ve meta-anotasyonlar.
2// Çalıştırma: java Ornek2.java
3import java.util.List;
4
5public class Ornek2 {
6
7    // @FunctionalInterface: bu arayüzün TEK soyut metotlu olduğunu garanti eder.
8    // İkinci soyut metot eklersen derleyici HATA verir (lambda hedefi bozulmasın diye).
9    @FunctionalInterface
10    interface Donusturucu {
11        int donustur(int x);
12        // default void log() {}  // default eklenebilir; ama 2. SOYUT metot eklenemez
13    }
14
15    public static void main(String[] args) {
16        Donusturucu kare = x -> x * x;       // functional interface -> lambda hedefi
17        Donusturucu artir = x -> x + 1;
18        System.out.println("kare(5) = " + kare.donustur(5));
19        System.out.println("artir(5) = " + artir.donustur(5));
20
21        // @SafeVarargs: jenerik varargs'ın güvenli olduğunu belirtir (uyarıyı bastırır).
22        System.out.println("\nilkler: " + ilkUcu("a", "b", "c", "d", "e"));
23
24        System.out.println("""
25
26                --- @FunctionalInterface, @SafeVarargs, meta-anotasyonlar ---
27                @FunctionalInterface: arayüzün TEK soyut metotlu kalmasını garanti eder (lambda hedefi). Belge + güvenlik.
28                @SafeVarargs: jenerik varargs metotlarındaki 'unchecked/heap pollution' uyarısını güvenle bastırır.
29                META-ANOTASYONLAR (anotasyonu tanımlarken kullanılır):
30                  @Retention: anotasyon ne kadar yaşar (SOURCE/CLASS/RUNTIME — reflection için RUNTIME).
31                  @Target: nereye uygulanabilir (TYPE, METHOD, FIELD...).
32                  @Inherited, @Documented, @Repeatable.
33                Kendi anotasyonunu tanımlama ve reflection ile okuma -> 'reflection-ve-annotations' konusu.""");
34    }
35
36    @SafeVarargs
37    static <T> List<T> ilkUcu(T... ogeler) {
38        return List.of(ogeler).subList(0, Math.min(3, ogeler.length));
39    }
40}
Çıktı yerel JDK 21 ile yakalandı — tarayıcıda JVM çalışmaz.