Saya Mencari jawaban pasti dari sumber primer atau sekunder untuk alasan (terutama) Java dan C # memutuskan untuk memiliki metode statis sebagai titik masuk mereka, daripada mewakili contoh aplikasi dengan turunan dari sebuah Application
kelas (dengan titik masuknya menjadi konstruktor yang tepat).
Latar belakang dan detail penelitian saya sebelumnya
Ini telah ditanyakan sebelumnya. Sayangnya, jawaban yang ada hanya mengemis pertanyaan . Secara khusus, jawaban berikut tidak memuaskan saya, karena saya anggap salah:
- Akan ada ambiguitas jika konstruktor kelebihan beban. - Faktanya, C # (dan juga C dan C ++) memungkinkan tanda tangan yang berbeda
Main
sehingga ambiguitas potensial yang sama ada, dan ditangani. - Sebuah
static
metode berarti tidak ada benda-benda dapat dipakai sebelum jadi urutan inisialisasi jelas. - Ini hanya faktual salah, beberapa objek yang dipakai sebelumnya (misalnya dalam konstruktor statis). - Jadi mereka dapat dipanggil oleh runtime tanpa harus instantiate objek induk. - Ini bukan jawaban sama sekali.
Sekedar alasan mengapa saya pikir ini adalah pertanyaan yang valid dan menarik:
Banyak kerangka kerja yang menggunakan kelas untuk mewakili aplikasi, dan konstruktor sebagai titik masuk. Misalnya, kerangka kerja aplikasi VB.NET menggunakan dialog utama khusus (dan konstruktornya) sebagai titik masuk 1 .
Baik Java maupun C # secara teknis tidak memerlukan metode utama. Yah, C # butuh satu untuk dikompilasi, tetapi Java bahkan tidak. Dan dalam kedua kasus itu tidak diperlukan untuk eksekusi. Jadi ini sepertinya bukan batasan teknis. Dan, seperti yang saya sebutkan di paragraf pertama, untuk konvensi belaka, tampaknya anehnya tidak sesuai dengan prinsip desain umum Java dan C #.
Untuk menjadi jelas, tidak ada kerugian spesifik untuk memiliki main
metode statis , itu hanya aneh , yang membuat saya bertanya-tanya apakah ada beberapa alasan teknis di baliknya.
Saya tertarik pada jawaban pasti dari sumber primer atau sekunder, bukan spekulasi belaka.
1 Meskipun ada panggilan balik ( Startup
) yang dapat mencegat ini.
sumber
Jawaban:
TL; DR
Di Jawa, alasannya
public static void main(String[] args)
adalah ituUntuk C #, alasannya hampir sama untuk berbicara. Perancang bahasa membuat sintaksis titik entri program tetap familier bagi programmer yang datang dari Jawa. Seperti yang dikatakan arsitek C #, Anders Hejlsberg ,
Versi panjang
berkembang di atas dan didukung dengan referensi yang membosankan.
Terminator java Hasta la vista Baby!
VM Spec, 2.17.1 Memulai Mesin Virtual
... lihat juga: Lampiran: Saya membutuhkan pakaian, sepatu bot, dan sepeda motor Anda
eksekusi ditargetkan untuk digunakan seperti skrip pada antarmuka baris perintah.
sidestep penting
... yang membantu menghindari beberapa jejak palsu dalam penyelidikan kami.
VM Spec, 1.2 Mesin Virtual Java
Saya perhatikan di atas ketika mempelajari bab sebelumnya - 1.1 Sejarah yang saya pikir bisa membantu (tetapi ternyata tidak berguna).
eksekusi diatur oleh VM spec saja, yang
secara eksplisit menyatakan bahwa itu tidak ada hubungannya dengan bahasa Java
=> OK untuk mengabaikan JLS dan apa pun yang terkait dengan bahasa Jawa sama sekali
Gosling: kompromi antara bahasa C dan scripting ...
Berdasarkan hal di atas, saya mulai mencari web untuk sejarah JVM . Tidak membantu, terlalu banyak sampah dalam hasil.
Kemudian, saya teringat legenda tentang Gosling dan mempersempit pencarian saya ke sejarah Jling Gosling .
Eureka! Bagaimana Spesifikasi JVM Datang
pernyataan eksplisit bahwa pada saat penciptaan,
C dan skrip dianggap sebagai pengaruh yang paling penting.
Sudah terlihat anggukan pada skrip di VM Spec 2.17.1,
argumen baris perintah cukup menjelaskan
String[] args
tetapi
static
danmain
belum ada di sana, perlu menggali lebih lanjut ...Catatan saat mengetik ini - menghubungkan C, scripting dan VM Spec 1.2 dengan tidak ada-nya-Jawa - Saya merasa seperti sesuatu yang akrab, sesuatu ... berorientasi objek perlahan berlalu. Pegang tanganku dan terus bergerak. Jangan memperlambat, kita hampir sampai
Slide utama tersedia secara online: 20_Gosling_keynote.pdf , cukup nyaman untuk menyalin poin utama.
A-ha! Mari kita lihat lebih dekat pada sintaks C .
Apakah kita semakin dekat? kamu bertaruh. Juga patut mengikuti tautan "utama" dari kutipan di atas:
Agar nyaman bagi pengembang C, titik masuk program harus
main
.Juga, karena Java membutuhkan metode apapun untuk berada di kelas,
Class.main
adalahsedekat karena mendapat: doa statis, hanya nama kelas dan dot,
tidak ada konstruktor menyenangkan - C tahu apa-apa seperti itu.
Ini juga transitif berlaku untuk C #, dengan mempertimbangkan
gagasan migrasi mudah untuk itu dari Jawa.
Pembaca yang berpikir bahwa titik masuk program yang familier tidak masalah diundang dengan ramah untuk mencari dan memeriksa pertanyaan Stack Overflow di mana orang-orang yang berasal dari Java SE mencoba menulis Hello World untuk Java ME MIDP. Catatan MIDP entry point tidak memiliki
main
atau tidakstatic
.Kesimpulan
Berdasarkan di atas saya akan mengatakan itu
static
,main
danString[] args
pada saat Jawa dan C # pilihan yang paling masuk akal untuk menentukan titik masuk program .Lampiran: Saya membutuhkan pakaian, sepatu bot, dan sepeda motor Anda
Harus mengakui, membaca VM Spec 2.17.1 sangat menyenangkan.
Referensi simbolis dari
Terminator
oh yeah.sumber
Itu hanya terasa agak kasar bagi saya. Konstruktor digunakan untuk inisialisasi objek: ia menetapkan objek, yang kemudian digunakan oleh kode yang membuatnya.
Jika Anda meletakkan fungsionalitas penggunaan dasar di dalam konstruktor, dan kemudian tidak pernah benar-benar menggunakan objek yang dibuat konstruktor dalam kode eksternal, maka Anda melanggar prinsip-prinsip OOP. Pada dasarnya, melakukan sesuatu yang sangat aneh tanpa alasan yang jelas.
Mengapa Anda tetap ingin melakukan itu?
sumber
Main
metode bekerja dengan baik untuk kasus sederhana, dan tidak benar-benar masalah dalam kasus-kasus sulit, jadi mengapa tidak?Untuk Jawa saya pikir alasannya sederhana: Ketika mengembangkan Jawa, para devs tahu bahwa kebanyakan orang yang belajar bahasa akan mengenal C / C ++ sebelumnya.
Oleh karena itu Java tidak hanya terlihat sangat mirip C / C ++ daripada mengatakan smalltalk, tetapi juga mengambil alih keistimewaan dari C / C ++ (pikirkan saja literal integer literal). Karena c / c ++ keduanya menggunakan metode utama, melakukan hal yang sama untuk java masuk akal dari sudut pandang itu.
Saya cukup yakin saya ingat bloch atau seseorang mengatakan sesuatu di sepanjang baris ini tentang mengapa mereka menambahkan literal integer oktal, saya akan melihat apakah saya dapat menemukan beberapa sumber :)
sumber
:
menjadiextends
? Danpublic static void main(String [ ] args)
di dalam kelas sangat berbeda dari diint main(int argc, char **argv)
luar kelas.:
keextends
adalah masalah sintaksis dan pada dasarnya sama. Semua lainnya ditentukan oleh bahasa.main()
, padahal tampaknya itu tidak cukup penting dalam kasus lain.Nah, ada banyak fungsi utama di luar sana yang menjalankan infinite loop. Konstruktor yang bekerja dengan cara ini (dengan objek yang tidak pernah dikonstruksi) adalah yang tampaknya aneh bagi saya.
Ada begitu banyak hal lucu tentang konsep ini. Logika Anda berjalan di atas objek yang belum lahir, objek yang dilahirkan untuk mati (karena mereka melakukan semua pekerjaan mereka di konstruktor), ...
Bukankah semua efek samping ini akan merusak lebih banyak gerobak OO daripada publik biasa (karena itu perlu diakses oleh yang tidak dikenal) statis (karena tidak ada contoh diperlukan bagi kita untuk memulai) batal main (karena itu adalah titik masuk )?
Untuk titik masuk fungsi yang sederhana, sederhana, agar ada di Jawa, publik dan statis akan secara otomatis diperlukan. Meskipun menjadi metode statis , itu bermuara pada apa yang bisa kita dapatkan lebih dekat dari fungsi polos untuk mencapai apa yang diinginkan: titik masuk sederhana.
Jika Anda tidak akan mengadopsi titik masuk fungsi yang sederhana, sederhana, sebagai titik masuk. Apa selanjutnya yang tampaknya tidak aneh sebagai konstruktor yang tidak dimaksudkan untuk dibangun?
sumber
Anda dapat dengan cepat menjalankan beberapa tes mandiri di kelas, selama pengembangan, dengan menempelkan
main()
di kelas yang Anda coba tes.sumber
Anda harus mulai dari suatu tempat. Main statis adalah lingkungan eksekusi paling sederhana yang dapat Anda miliki - tidak ada instance apa pun (di luar JVM dan parameter string sederhana) perlu dibuat - sehingga dapat "muncul" dengan minimum keributan (dan kemungkinan rendah) kesalahan pengkodean mencegah startup, dll) dan dapat melakukan hal-hal sederhana tanpa banyak pengaturan lainnya.
Pada dasarnya aplikasi KISS.
[Dan, tentu saja, alasan utamanya adalah: Mengapa tidak?]
sumber
Menurut pemahaman saya, alasan utamanya sederhana. Sun adalah perusahaan Unix yang menjual mesin Unix dan Unix adalah apa yang C "main (args)" konvensi untuk memohon biner .
Selain itu Java secara eksplisit dirancang agar mudah diambil untuk programmer C dan C ++, jadi tidak ada alasan yang baik untuk tidak hanya sekadar mengambil konvensi C.
Pendekatan yang dipilih di mana setiap kelas dapat memiliki metode doa cukup fleksibel, terutama dalam kombinasi dengan
Main-Class
baris dalam file MANIFEST.MF di jar yang bisa dijalankan.sumber
Ini tidak konsisten dengan filosofi OOP bahwa suatu program akan menjadi objek dari sudut pandang proses OS, karena tidak ada cara untuk memiliki lebih dari satu menurut definisi.
Selain itu, konstruktor bukanlah titik masuk dengan cara apa pun.
Sepertinya saya adalah pilihan paling masuk akal untuk memiliki fungsi utama sebagai statis, yang sebenarnya ada di akhir hari. Mengingat arsitektur VM seperti JVM dan CLR, pilihan lain tidak perlu mendorongnya.
sumber
Runnable
objek instantiating untuk memiliki beberapa utas.