17 puan yazan GN⁺ 2025-09-18 | 5 yorum | WhatsApp'ta paylaş
  • Artık Java’daki ilk program public static void main(String[] args) ile başlamak zorunda değil; bunun yerine sadeleştirilmiş void main() sözdizimiyle yazılabiliyor
  • Yeni sözdiziminde IO.readln ve IO.println gibi basit çağrılarla girdi/çıktı işlemleri yapılabildiği için kod çok daha sezgisel hale geliyor
  • Mevcut new Scanner(System.in), System.out.println gibi uzun ve ayrıntılı ifadeler artık gereksiz hale geliyor
  • Uzun süredir rahatsızlık veren bu durum “nihayet sona erdi”; artık Java’nın temel yapısı hafiflerken başlangıç eşiğinin düşmesi ve öğrenme dostuluğunun artması bekleniyor

  • Geleneksel olarak Java, programın başlaması için public static void main(String[] args) şeklinde uzun bir bildirim gerektiriyordu
  • Ancak 16 Eylül 2025 itibarıyla, Java’nın en temel ilk örneği olarak görülen main fonksiyonunun karmaşık bildirimi yeni ve basit bir biçimle değiştirildi
  • Eski yöntem:
    public class Main {  
        public static void main(String[] args) {  
            Scanner scanner = new Scanner(System.in);  
            System.out.print("What is your name? ");  
            String name = scanner.nextLine();  
            System.out.println("Hello, " + name);  
        }  
    }  
    
  • Yeni yöntem:
    void main() {  
        var name = IO.readln("What is your name? ");  
        IO.println("Hello, " + name);  
    }  
    
  • Bunun, yeni başlayanlar için gereksiz yere uzun olduğu ve ancak bir “sihirli söz” gibi ezberlenerek kullanılabildiği eleştirisi uzun zamandır yapılıyordu
  • Eski bildirim biçiminin zahmeti ve anlaşılmazlığı giderilirken, kısa sözdiziminin eklenmesiyle kod okunabilirliği arttı ve Java’ya giriş eşiği büyük ölçüde düştü
    • Artık temel örneklerde Scanner, System.out.println gibi karmaşık nesne oluşturma ve çağrılar kullanılmıyor

Good Fucking Riddance = “Nihayet ortadan kalktı da içimiz rahatladı. Güle güle.”

5 yorum

 
kayws426 2025-09-22

Başka bir yöntemin yeni eklenmiş olması, mevcut yöntemin öldüğünü söylemek gibi geliyor.
Gerçekten mevcut yöntemi artık kullanamıyor muyuz ve mutlaka yeni yöntemi mi kullanmamız gerekiyor?

 
jhk0530 2025-09-19

Vay canına

 
jwh926 2025-09-18

Java'yı yeniden mi öğrenmem gerekiyor..

 
carnoxen 2025-09-18

Main öldü. Yaşasın main!

 
GN⁺ 2025-09-18
Hacker News görüşü
  • Zaman geçtikçe böyle yabancı görünen kodların giderek anlaşılır hale gelmesi sürecini özleyeceğimi düşünüyorum. İlk başta Python öğrendikten sonra Java'ya geçtiğimde void ya da String[] gibi tiplerin ne anlama geldiğini bilmediğim için ilginç gelmişti. Tipleri öğrendikten sonra anlamaya başladım; sonra class ve object kavramlarını, ardından da main'in neden static bir metot olarak var olduğunu öğrendim. Daha derine indikçe bu class'ın ne zaman çağrıldığını da öğrendim ve başta yalnızca boilerplate gibi görünen kod zamanla anlam kazanmaya başladı. Muhtemelen deneyimli Java geliştiricileri o tek satırdan benden çok daha fazla anlam çıkarabiliyordur. Yine de artık ortadan kalkıyor olması içimi rahatlatıyor

    • Gerçekten iç rahatlatıcı. Son 30 yılda yazılım eğitimi, geliştiricilere "mühendislik" adı altında gereksiz karmaşıklık üretmeyi öğretti. Örneğin A geliştiricisi, entry point, callback, interface ya da ihtiyaç duyduğu her şey için class oluşturur. Sonuçta elimizde class'lar olur. B geliştiricisi bu class'lara instance değişkenleri ekleyerek her şeyi değiştirilebilir hale getirir ve böylece "implementation mud" oluşur. Sonra başka bir geliştirici kodu yeniden kullanmak için inheritance ekler ama bu da daha fazla karmaşıklık ve dynamic dispatch kâbusu getirir. Sonunda referans döngüleri oluşur ve object'lerin bağlantı ilişkileri içinden çıkılmaz hale gelir. Zaman geçtikçe refactoring daha zor ve daha can sıkıcı olur; sonunda da kodu silip baştan yazarsınız

    • Üniversitede ilk kez programlama öğrenirken bu kodu görüp hocanın "normalde kodun tamamını açıklarım ama bu kısmı şimdilik olduğu gibi kabul edin" dediğini hatırlıyorum. Sonradan dönüp baktığımda, bu kodu tamamen anladığımı fark ettiğim an oldukça hoş bir deneyimdi. Yine de artık zaman değişiyor gibi ve bu da içimi ferahlatıyor

    • Aslında static class metodu, programın tek bir entry point'inin zorunlu olarak bir class ile ilişkili olması gerektiği şeklindeki gerçeklik inkârına oldukça yakın. Sadece C++ değil, Python ve Ruby gibi prosedürel gerçekliği kabul eden diller de var; Java ise sanki kullanıcının gözünü bağlayıp onu "kusursuz OOP dünyasına" itmeye çalışıyor

    • Eski class tabanlı yaklaşımı bilen biri olarak yeni stilin (Java 21'deki unnamed classes gibi) daha çok soru doğurduğunu düşünüyorum. Java gerçekten "her şey object'tir" yaklaşımından çıkıp prosedürel bir dil mi oluyor diye merak ediyorum. Komut satırı argümanları gerektiğinde bunun nasıl yapılacağını da merak ediyorum. Genelde Java'dan uzak durduğum için çok bilmiyorum ama bunu gerçekten samimi bir soru olarak soruyorum

  • Java 1.2 döneminde standart girdi şöyle okunuyordu. Scanner class'ı benim için yeni olduğu için yabancı geliyor

BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String input = in.readLine();
  • Benim de benzer bir deneyimim var. Uzun zaman önce Java kullandığım için public static void main kalıbı tanıdıktı ama Scanner kullanımının neden farklı hissettirdiğini tam olarak anlayamıyordum

  • Benim deneyimime göre büyük projelerde onlarca yıl çalıştıktan sonra main fonksiyonunun nasıl yazıldığı günlük işimi ya da kariyerimi hiç etkilemiyor. Bu yüzden bunun pratikte ne kadar etki yarattığını merak ediyorum

    • Android geliştiricileri için zaten main diye bir kavram yoktu. Açıkçası önemsiz bir Hello World örneğinin çirkin görünmesi, bir dilin daha karmaşık şeyleri de kötü yönettiğinin göstergesi değildir

    • Birçok insan Java ile programlamaya başlarken main'i onlarca kez yazdı ama bunun ne anlama geldiğini hiç bilmiyordu

    • Profesyonel geliştirici için etkisi büyük olmayabilir ama yeni başlayanlar için önemli bir mesele. Eskiden Java öğrettim; "Hello, World" yazdırmadan önce ezberlenmesi gereken sihirli sözler (boilerplate), öğrenciler için bir giriş engeli oluşturuyordu

    • Komut satırı arayüzü yapıyorsanız etkisi olabilir ama Java ile CLI yapan çok fazla kişi yok

    • Son 5 yıldır bir codebase içinde main gördüğümü hatırlamıyorum. Ayrıca neredeyse hiç sıfırdan yeni bir class yazmıyorum; genelde framework'e özgü bir class'ı implement ediyor ya da extend ediyorum

  • JEP 445: Unnamed Classes and Instance Main Methods, Java 21 ile yayımlandı
    https://openjdk.org/jeps/445

    • Ne yazık ki bu özelliğin yalnızca tek dosyalı programlarda kullanılabilmesi hayal kırıklığı yaratıyor. Paket seviyesinde metotlara ya da bir dosyada birden çok class/record tanımına izin verilseydi Java daha iyi olabilirdi. Ama her hâlükârda bunun "Java kodunun genel yazım tarzını etkilemesi" istenmemiş gibi görünüyor
  • 30 yıl sonra Java'nın nihayet oldukça iyi bir dile evrildiğini görmek şaşırtıcı

    • Framework kullanmadan saf Java ve C++ ile çok kod yazdım; o zamanlar boilerplate çok daha azdı ve işler daha basitti. Gerçek anlamda rahatlama hissettiğim dönem, yaklaşık 10 yıl önce lambda'ların eklenmesiydi. Lambda'larla birlikte kod miktarı azaldı ve geliştirme deneyimi belirgin biçimde daha keyifli hale geldi. Java uzun süre aşırı derecede açık seçik, çok küçük şeyler için bile yalnızca yazım hatası denetimi yapıyormuş gibi hissettiren gereksiz tekrarlarla doluydu. Kotlin yükselmeden önce atmosfer buydu; sonrasında lambda'lar ve anonim class'lar gibi özelliklerle geliştirme deneyimi ciddi biçimde iyileşti

    • Java'nın korkunç bir dil olduğu iddiası fazla abartılı

    • Öte yandan Python gibi dillerin 30 yıl sonra bile hâlâ rahatsız edici olduğunu düşünüyorum

    • Muhtemelen gerçekten kötü bir dil deneyimlemediniz ya da "korkunç değil" için çıtanız aşırı yüksek

    • Yine de Java'nın mükemmel geriye dönük uyumluluğu ve paket yönetim sistemi gerçekten etkileyici

  • Önceki yorumda da söylediğim gibi, bir Java geliştiricisi olarak Python bana daha tuhaf geliyor ama mevcut yaklaşımın kötü olduğunu düşünmüyorum. Yine de soyutlamanın temellerini anlamadan doğrudan programlamaya başlamak, "programlamaya giriş" için iyi bir tercih olmayabilir. Bir araç amaç odaklı, paradigma odaklı vb. biçimde tasarlandığında bazen aşırı soyutlama ortaya çıkabiliyor. Java OOP odağında tasarlandığı için interface gibi yapı taşlarıyla düşünmek doğal geliyor. Metot/class erişim belirleyicileri de kime yönelik olduklarına göre net biçimde ayrılıyor (public, protected, default, private vb.). Yani Java'ya giriş, kullanıcıya (programcıya) dönük interface'in görünürlüğünden başlıyor. Garip görünebilir ama en azından tutarlı

    • Ağır sözdiziminin OOP ile doğrudan bir ilgisi yok. Java ortaya çıkmadan önce OOP'nin hiçbir tanımı "fonksiyonlar class dışında var olamaz" demiyordu. Sun uzun süre standalone fonksiyon fikrini reddetti (static import Java 5'te, closure Java 8'de, compact source files/instance main ise ancak şimdi geldi); bunun sonucunda tüm fonksiyonlar hâlâ class'ların içinde yer alıyor. Bu daha çok pratiklik ve uyumlulukla ilgili, felsefi bir mesele değil. "Her şey object'tir" anlayışını zorlamaya çalıştılar ama sonra primitive değerleri de ekleyerek kendi içinde çeliştiler. Fonksiyonların mutlaka class içinde olmasının pratik bir faydası yok. Hatta integer gibi değerler üzerinde metot tanımlanabilseydi daha iyi olurdu. Bu arada Smalltalk gibi "saf OOP" dillerde class dışında serbestçe fonksiyon tanımlanabiliyor ve REPL içinde doğrudan kod çalıştırılabiliyor
      İlgili bağlantı

    • Hello World'ün önemli olmasının nedeni, hem programı çalıştırmak için gereken boilerplate'i hem de gerçek çıktı kodunu aynı anda göstermesidir. Ayrıca build tool yapılandırması açısından bakıldığında, bazı kısımlar aslında boilerplate'ten çok eğitim/araç kurulumu prosedürüdür. Bu hemen açıklanırsa büyük bir sorun olmaz

  • Eğer derleyici içeride class oluşturmak için bir hile yapıyorsa, bu yalnızca göstermelik bir değişiklik olur. Başka top-level fonksiyonlara izin verilmiyorsa sonuçta bu da sadece özel bir durum olur ve yine tuhaf kalır

    • C# 9.0'dan beri top-level statement desteği veriyor ama sonuçta içeride statik bir metoda dönüştürülüyor. Birden fazla top-level fonksiyon da benzer şekilde çalışıyor. Gerçek örnek: C# decompiled example
      Bu tür hileler aslında faydalı derleyici dönüşümlerine iyi bir örnek (closure, async state machine vb.). Bu değişiklik de o türden sayılabilir

    • C/C++'ta yalnızca main() için varsayılan return 0 uygulanması da benzer şekilde biraz tuhaf hissettiriyor

    • Eğer yalnızca main top-level fonksiyon olarak izin alıyor ve başka hiçbir şeye izin verilmiyorsa, bunun da çok iyi bir değişiklik olduğunu düşünmüyorum

  • Java kod örneklerinde neden import satırlarının atlandığını anlamıyorum. Boilerplate karmaşıklığını göstermek istiyorsanız import'ları da mutlaka yazmalısınız

    • Genelde IDE import'ları otomatik yönettiği için insanlar bunu düşünmüyor. I/O ile ilgili class'larda compact örneklerde ayrıca import gerekmiyor; yani kod gerçekten o hâliyle çalışıyor

    • Çoğu Java IDE'si import'ları otomatik yönetir

  • public static void main(String[] args) entry point'ini C#'taki gibi top-level statement paradigmasıyla soyutlamak boilerplate'i azaltıp kodu sadeleştirebilir gibi görünüyor; neden bunu yapmadıklarını merak ediyorum

    • Paving the on-ramp belgesine bakabilirsiniz

    • Eğer entry point zaten özel bir istisna durumu olarak var olacaksa, bu OOP'nin sınırlarının kabul edildiği anlamına gelir. O halde daha cesur bir yeni alternatif tasarlamak daha iyi olmaz mı diye düşünüyorum

  • Unnamed class yaklaşımının, global değişkenleri uygulamayı kolaylaştırması, hot reload imkânı sunması ve sözdizimini sadeleştirmesi hoşuma gidiyor. Öte yandan Java dosyalarının adının public class ile aynı olması gerektiği kısıtı var; bu yüzden belki de sadece public class X { } kısmını isteğe bağlı hale getirip gerektiğinde yazmak yeterli olabilirdi. Neden anonim class getirme yoluna gidildiğini çok anlamıyorum
    Derleyici yine de bunu HelloWorld.class gibi bir class'a dönüştürüyor; yani o isim uygulama ayrıntısından ibaret ve kaynak kodda doğrudan kullanılamıyor
    https://openjdk.org/jeps/445