Mengapa metode utama Java statis?


505

Tanda tangan metode metode main Java () adalah:

public static void main(String[] args){
    ...
}

Apakah ada alasan untuk metode ini statis?


1
dalam hal ini, kita tidak boleh mengatakan tanda tangan metode , karena istilah ini hanya merujuk pada nama metode dan parameternya
Andrew Tobilko

Java sengaja dirancang agar terlihat familier bagi seorang programmer C. Ini sangat dekat dengan konvensi C.
Thorbjørn Ravn Andersen

Jawaban:


337

Metode ini statis karena jika tidak akan ada ambiguitas: konstruktor mana yang harus dipanggil? Terutama jika kelas Anda terlihat seperti ini:

public class JavaClass{
  protected JavaClass(int x){}
  public void main(String[] args){
  }
}

Haruskah panggilan JVM new JavaClass(int)? Apa yang harus dilaluinya x?

Jika tidak, haruskah JVM instantiate JavaClasstanpa menjalankan metode konstruktor? Saya pikir itu tidak boleh, karena itu akan menjadi kasus khusus seluruh kelas Anda - kadang-kadang Anda memiliki contoh yang belum diinisialisasi, dan Anda harus memeriksanya dalam setiap metode yang dapat dipanggil.

Ada terlalu banyak kasus tepi dan ambiguitas sehingga tidak masuk akal jika JVM harus membuat instance kelas sebelum titik masuk dipanggil. Itu sebabnya mainstatis.

Saya tidak tahu mengapa mainselalu ditandai public.


4
Menerapkan antarmuka tidak menyelesaikan masalah instantiasi.
Jacob Krall

26
Saya pribadi suka itu public static void mainberfungsi sebagai penanda titik masuk - konstruktor tanpa parameter publik tidak berteriak, "Ini mungkin titik masuk!" di jalan yang sama.
Jacob Krall

5
@ EdwinDalorzo - Apa yang akan diperoleh dengan memaksa kelas entry point menjadi instantiated? Memanggil metode statis menempatkan jumlah beban paling sedikit di kelas. Ini gratis untuk instantiate sendiri jika itu lebih masuk akal untuk desain Anda.
David Harkness

18
"Konstruktor mana yang harus dipanggil?" Bagaimana itu bisa menjadi masalah? "Masalah" yang sama ada untuk keputusan yangmain akan dihubungi. Cukup aneh (untuk Anda), JVM mengelola ini dengan baik.
Konrad Rudolph

9
Metode utama selalu publik karena harus diakses oleh mesin runtime, JVM.
gthm

398

Ini hanya konvensi. Bahkan, bahkan nama main (), dan argumen yang disampaikan murni konvensi.

Ketika Anda menjalankan java.exe (atau javaw.exe pada Windows), yang sebenarnya terjadi adalah beberapa panggilan Java Native Interface (JNI). Panggilan ini memuat DLL yang benar-benar JVM (itu benar - java.exe BUKAN JVM). JNI adalah alat yang kami gunakan ketika kami harus menjembatani dunia mesin virtual, dan dunia C, C ++, dll ... Kebalikannya juga benar - tidak mungkin (setidaknya setahu saya) untuk benar-benar mendapatkan JVM berjalan tanpa menggunakan JNI.

Pada dasarnya, java.exe adalah aplikasi C super sederhana yang mem-parsing baris perintah, membuat array String baru di JVM untuk menampung argumen tersebut, mem-parsing nama kelas yang Anda tentukan mengandung main (), menggunakan panggilan JNI untuk menemukan metode main () itu sendiri, kemudian memanggil metode main (), meneruskan dalam array string yang baru dibuat sebagai parameter. Ini sangat, sangat mirip dengan apa yang Anda lakukan ketika Anda menggunakan refleksi dari Jawa - hanya menggunakan panggilan fungsi asli yang membingungkan sebagai gantinya.

Ini akan sangat legal bagi Anda untuk menulis versi java.exe Anda sendiri (sumber didistribusikan dengan JDK) dan minta ia melakukan sesuatu yang sama sekali berbeda. Sebenarnya, itulah yang kami lakukan dengan semua aplikasi berbasis Java kami.

Setiap aplikasi Java kami memiliki peluncurnya sendiri. Kami terutama melakukan ini sehingga kami mendapatkan ikon dan nama proses kami sendiri, tetapi itu berguna dalam situasi lain di mana kami ingin melakukan sesuatu selain panggilan utama () biasa untuk menyelesaikan sesuatu (Misalnya, dalam satu kasus kami melakukan Interoperabilitas COM, dan kami benar-benar mengirimkan pegangan COM ke main () alih-alih array string).

Jadi, panjang dan pendek: alasannya statis adalah b / c itu nyaman. Alasan itu disebut 'utama' adalah bahwa itu harus sesuatu, dan main () adalah apa yang mereka lakukan di masa lalu C (dan pada masa itu, nama fungsi itu penting). Saya kira java.exe dapat memungkinkan Anda untuk hanya menentukan nama metode utama yang sepenuhnya memenuhi syarat, bukan hanya kelas (java com.mycompany.Foo.someSpecialMain) - tetapi itu hanya mempersulit IDE untuk mendeteksi secara otomatis ' kelas yang dapat diluncurkan 'dalam suatu proyek.


66
+1: Sangat menarik (terutama bagian tentang menulis kebiasaan java.exe)
Adam Paynter

9
Menarik, saya tidak setuju dengan "Ini hanya konvensi." Bagian dari jawabannya. Pertanyaan utama OP adalah alasan statis dalam deklarasi. Saya tidak berpikir staticdalam main()deklarasi itu hanya demi konvensi. Fakta bahwa itu `main () 'dan bukan sesuatu yang lain yang layak.
Jared

2
@ David Jadi begitu. Saya sebenarnya lebih suka jawaban dari salah satu orang yang awalnya terlibat - tetapi itu adalah kesempatan yang sangat jauh. Sebagian besar jawaban lain sayangnya merupakan latihan dalam penalaran ad-hoc. Yang ini memberikan detail yang cukup menarik, selain memiliki kerendahan hati untuk tidak menciptakan detail teknis yang salah untuk alasan (mungkin) penyebab non-teknis.
Konrad Rudolph

2
@ Jared - Mereka bisa memerlukan konstruktor no-arg publik dan dibuat mainnon-statis dan masih sesuai dalam batas-batas bahasa. Tanpa mendengar dari para desainer, kita hanya harus setuju untuk tidak setuju. :)
David Harkness

4
@ BenVoigt Anda memanggil LoadLibrary () untuk mendapatkan jvm dll. Kemudian Anda memanggil getprocaddress ("JNI_CreateJavaVM"), lalu Anda memanggil fungsi JNI_CreateJavaVM ( docs.oracle.com/javase/1.4.2/docs/guide/jni/spec/… ). Setelah VM dimuat, Anda menggunakan panggilan JNI standar untuk menemukan kelas yang benar, memuat metode utama statis dan memohonnya. Tidak ada banyak ruang untuk salah tafsir di sana. JNI benar-benar bagaimana Anda memuat VM. Anda dapat digunakan untuk menulis hanya sisi klien JNI menggunakan kata kunci asli, javah-jni, dll ... tapi itu hanya setengah dari JNI.
Kevin Day

188

The main()metode C++, C#dan Javastatis
Karena mereka kemudian dapat dipanggil oleh mesin runtime tanpa harus instantiate benda maka kode tersebut di dalam tubuh dari main()akan melakukan sisanya.


1
Baiklah tapi tidak bisakah runtime instantiate satu objek kelas? Dan kemudian memanggil metode Utama? Mengapa?
Andrei Rînea

12
Bagaimana JVM tahu konstruktor mana yang harus dihubungi, jika kelas utama Anda memiliki konstruktor yang terlalu banyak? Parameter apa yang akan dilewatinya?
Jacob Krall

1
@Noah ketika Anda mengatakan kelas induk, maksud Anda kelas yang berisi metode utama? Karena jika demikian, istilah "kelas induk" agak membingungkan di sini, dan kalau tidak, itu tidak masuk akal bagi saya. Juga, jika berdasarkan konvensi yang kami gunakan public static void main..., mengapa konvensi tidak dapat dilakukan karena kelas titik masuk aplikasi harus memiliki konstruktor default publik?
Edwin Dalorzo

2
@ Jacob Bagaimana JVM tahu yang kelebihan beban static void mainuntuk menelepon? Tidak masalah sama sekali.
Konrad Rudolph

4
@Namratha: Ya, Anda melewatkan sesuatu. Tidak benar bahwa "metode statis tidak dapat merujuk metode non-statis". Pernyataan yang benar adalah: "Setiap metode statis harus menyediakan objek saat menggunakan metode non-statis". Dan lihat, staticmetode seperti yang mainsering digunakan newuntuk membuat objek seperti itu.
Ben Voigt

38

Mengapa public static void main (String [] args)?

Ini adalah bagaimana Bahasa Jawa dirancang dan Java Virtual Machine dirancang dan ditulis.

Spesifikasi Bahasa Oracle Java

Lihat Bab 12 Eksekusi - Bagian 12.1.4 Laksanakan Test.main :

Akhirnya, setelah selesai inisialisasi untuk Tes kelas (di mana pemuatan konsekuensial lainnya, menghubungkan, dan inisialisasi mungkin terjadi), metode utama Uji dipanggil.

Metode utama harus dinyatakan publik, statis, dan tidak berlaku. Itu harus menerima argumen tunggal yang merupakan array dari string. Metode ini dapat dinyatakan sebagai salah satu

public static void main(String[] args)

atau

public static void main(String... args)

Spesifikasi Oracle Java Virtual Machine

Lihat Bab 2 Konsep Bahasa Pemrograman Java - Bagian 2.17 Eksekusi :

Mesin virtual Java memulai eksekusi dengan memanggil metode utama dari beberapa kelas yang ditentukan dan memberikannya argumen tunggal, yang merupakan array dari string. Ini menyebabkan kelas yang ditentukan dimuat (§2.17.2), ditautkan (§2.17.3) ke tipe lain yang digunakannya, dan diinisialisasi (§2.17.4). Metode utama harus dinyatakan publik, statis, dan tidak berlaku.

Oracle OpenJDK Source

Unduh dan ekstrak toples sumber dan lihat bagaimana JVM ditulis, periksa ../launcher/java.c, yang berisi kode C asli di belakang perintah java [-options] class [args...]:

/*
 * Get the application's main class.
 * ... ...
 */
if (jarfile != 0) {
    mainClassName = GetMainClassName(env, jarfile);

... ...

    mainClass = LoadClass(env, classname);
    if(mainClass == NULL) { /* exception occured */

... ...

/* Get the application's main method */
mainID = (*env)->GetStaticMethodID(env, mainClass, "main",
                                   "([Ljava/lang/String;)V");

... ...

{    /* Make sure the main method is public */
    jint mods;
    jmethodID mid;
    jobject obj = (*env)->ToReflectedMethod(env, mainClass,
                                            mainID, JNI_TRUE);

... ...

/* Build argument array */
mainArgs = NewPlatformStringArray(env, argv, argc);
if (mainArgs == NULL) {
    ReportExceptionDescription(env);
    goto leave;
}

/* Invoke main method. */
(*env)->CallStaticVoidMethod(env, mainClass, mainID, mainArgs);

... ...

4
Masalahnya di sini adalah bahwa ini sebenarnya jawaban yang sangat baik untuk pertanyaan dalam bentuk aslinya, dengan banyak referensi (+1). Namun, saya ingin belajar tentang alasan untuk keputusan desain membuat metode statis sebagai titik masuk, daripada metode konstruktor atau contoh.
Konrad Rudolph

1
@KonradRudolph, untuk pertanyaan tentang bahasa dan desain spesifikasi JVM, mungkin Anda bisa mencoba menghubungi sumber asli dari Oracle dan melihat apakah Anda bisa mendapatkan umpan balik positif.
yorkw

2
Secara umum ketika perhitungan hasil metode hanya bergantung pada parameternya, sehingga tidak tergantung pada keadaan internal misalnya objek, itu bisa statis. Dan disarankan untuk mengaturnya sebagai statis untuk pemeliharaan kode / penggunaan kembali. Jika metode mainini tidak statis, itu berarti keadaan instance kelas harus diketahui dan jauh lebih kompleks untuk didefinisikan, seperti konstruktor mana yang harus digunakan terlebih dahulu.
Yves Martin

@KonradRudolph Menariknya, Oak (pendahulu Jawa) sudah memerlukan metode utama untuk memiliki prototipe yang serupa: public static void main(String arguments[])- Referensi: Oak 0.2 Spec .
assylias

2
@Yves Itu bisa . Tidak perlu, jika desain lain masuk akal. Saya telah mendengar beberapa argumen yang bagus dalam komentar di sini, tetapi saya masih berpikir bahwa suatu proses secara efektif sangat mirip dengan utas (itu adalah ), dan utas di Jawa biasanya direpresentasikan sebagai contoh dari Runnable. Mewakili seluruh proses dengan cara yang sama (yaitu memiliki Runnable.Runsebagai titik masuk) jelas masuk akal di Jawa. Tentu saja, Runnableitu sendiri bisa dibilang cacat desain, disebabkan oleh fakta bahwa Java tidak memiliki metode anonim (belum). Tapi karena sudah ada di sana ...
Konrad Rudolph

36

Mari kita pura-pura saja static tidak akan diperlukan sebagai titik masuk aplikasi.

Kelas aplikasi akan terlihat seperti ini:

class MyApplication {
    public MyApplication(){
        // Some init code here
    }
    public void main(String[] args){
        // real application code here
    }
}

Perbedaan antara kode konstruktor dan mainmetode diperlukan karena dalam OO berbicara seorang konstruktor hanya akan memastikan, bahwa sebuah instance diinisialisasi dengan benar. Setelah inisialisasi, instance dapat digunakan untuk "layanan" yang dimaksud. Menempatkan kode aplikasi lengkap ke dalam konstruktor akan merusaknya.

Jadi pendekatan ini akan memaksa tiga kontrak berbeda pada aplikasi:

  • Ada harus menjadi konstruktor default. Kalau tidak, JVM tidak akan tahu konstruktor mana yang harus dipanggil dan parameter apa yang harus disediakan.
  • Ada harus menjadi mainmetode 1 . Ok, ini tidak mengherankan.
  • Kelas tidak boleh abstract. Kalau tidak, JVM tidak bisa membuat instantiate.

The staticpendekatan di sisi lain hanya membutuhkan satu kontrak:

  • Harus ada mainmetode 1 .

Di sini tidak ada abstractbeberapa konstruktor yang penting.

Karena Java dirancang untuk menjadi bahasa yang sederhana bagi pengguna , tidak mengherankan bahwa juga titik masuk aplikasi telah dirancang dengan cara sederhana menggunakan satu kontrak dan tidak dengan cara yang rumit menggunakan tiga kontrak independen dan rapuh.

Harap dicatat: Argumen ini bukan tentang kesederhanaan di dalam JVM atau di dalam JRE. Argumen ini adalah tentang kesederhanaan bagi pengguna .


1 Di sini tanda tangan lengkap hanya dihitung sebagai satu kontrak.


1
Sebenarnya, persyaratan yang lebih kompleks: harus ada mainmetode yang public, staticdan memiliki tanda tangan void main(String[]). Saya setuju bahwa, jika metode ini adalah metode contoh, JRE akan memiliki pekerjaan sedikit lebih tetapi jenis pekerjaan akan sama, dan kompleksitasnya tidak jauh lebih tinggi (lihat diskusi dalam komentar dari jawaban sebelumnya). Saya tidak percaya bahwa perbedaan ini bertanggung jawab atas keputusan untuk menjadikan entry point statis, khususnya karena metode yang diperlukan untuk penyelesaian metode instance ada, dan siap digunakan.
Konrad Rudolph

3
@KonradRudolph: Maksud saya bukan tentang pekerjaan yang harus dilakukan JRE. Maksud saya adalah memaksa setiap pengguna bahasa untuk mengikuti lebih banyak kontrak seperlunya. Dalam pengertian ini static public main(String[])metode adalah satu tanda tangan dan karenanya satu kontrak. Kalau tidak, tiga kontrak independen harus diikuti.
AH

1
Ah. Saya masih tidak setuju bahwa ini ada bedanya. Kelas entry point dapat diimplementasikan dengan baik Runnable. Jelas, Java mengharapkan pengembang untuk mengikuti kontrak itu sepanjang waktu, mengapa harus terlalu banyak untuk titik masuk aplikasi? Itu tidak masuk akal.
Konrad Rudolph

3
@KonradRudolph: Tidak ada kontradiksi: Dalam satu kasus sistem akan memaksa tiga kontrak pada pengguna. Kontrak yang meragukan, yang tidak dapat diperiksa melalui kompiler dan yang, dari sudut pandang pengguna, independen. Dalam kasus biasa Threaddan Runnabletidak ada yang disembunyikan dari pengguna, ia dapat dengan jelas melihat apa yang terjadi dan ia memiliki perubahan untuk menerapkan hanya kontrak-kontrak yang cocok untuknya - ia memegang kendali, bukan sistem.
AH

2
Ini jawaban terbaik di sini. Sayang sekali bahwa banyak pengguna hanya akan membaca 2 atau 3 jawaban teratas pada halaman; dan yang ini tidak mungkin sampai di sana dalam waktu dekat. Ini menyebutkan poin penting dari konstruktor HANYA untuk inisialisasi - dan oleh karena itu tidak masuk akal untuk kode dalam gaya di mana konstruktor menjalankan seluruh aplikasi.
Dawood ibn Kareem

14

Jika tidak, konstruktor mana yang harus digunakan jika ada lebih dari satu?

Ada informasi lebih lanjut tentang inisialisasi dan pelaksanaan program Java yang tersedia di Spesifikasi Bahasa Jawa .


12

Sebelum metode utama dipanggil, tidak ada objek yang dipakai. Memiliki kata kunci statis berarti metode dapat dipanggil tanpa membuat objek apa pun terlebih dahulu.


Salah. Atau setidaknya sangat tidak aman. kelas publik Utama {objek objek statis = Objek baru () {{System.out.println ("objek dibuat"); }}; public static static utama (String [] args) {System.out.println ("in main"); }}
eljenso

Komentar yang adil. Secara teknis, saya seharusnya mengatakan bahwa sebelum metode Utama dipanggil, kelas yang mengandung metode utama tidak dipakai.
BlackWasp

12

Karena jika tidak, itu akan membutuhkan instance objek yang akan dieksekusi. Tetapi harus dipanggil dari awal, tanpa membangun objek terlebih dahulu, karena biasanya tugas fungsi utama () (bootstrap), untuk mengurai argumen dan membangun objek, biasanya dengan menggunakan parameter argumen / program ini.


10

Biarkan saya menjelaskan hal-hal ini dengan cara yang lebih sederhana:

public static void main(String args[])

Semua aplikasi Java, kecuali applet, memulai eksekusi dari main().

Kata kunci publicadalah pengubah akses yang memungkinkan anggota dipanggil dari luar kelas.

static digunakan karena memungkinkan main() dipanggil tanpa harus membuat instance instance dari kelas itu.

voidmenunjukkan bahwa main()tidak mengembalikan nilai apa pun.


9

Apa artinya public static void main(String args[])?

  1. public adalah specifier akses yang berarti siapa pun dapat mengakses / menjalankannya seperti JVM (Java Virtual Machine.
  2. staticmemungkinkan main()untuk dipanggil sebelum objek kelas telah dibuat. Ini perlu karena main()dipanggil oleh JVM sebelum benda dibuat. Karena ini statis, ia dapat langsung dipanggil melalui kelas.

    class demo {    
        private int length;
        private static int breadth;
        void output(){
            length=5;
            System.out.println(length);
        }
    
        static void staticOutput(){
            breadth=10; 
            System.out.println(breadth);
        }
    
        public static  void main(String args[]){
            demo d1=new demo();
            d1.output(); // Note here output() function is not static so here
            // we need to create object
            staticOutput(); // Note here staticOutput() function is  static so here
            // we needn't to create object Similar is the case with main
            /* Although:
            demo.staticOutput();  Works fine
            d1.staticOutput();  Works fine */
        }
    }

    Demikian pula, kami menggunakan kadang-kadang statis untuk metode yang ditentukan pengguna sehingga kami tidak perlu membuat objek.

  3. voidmenunjukkan bahwa main()metode yang dideklarasikan tidak mengembalikan nilai.

  4. String[] argsmenentukan satu-satunya parameter dalam main()metode ini.

    args- parameter yang berisi larik objek bertipe kelas String.


6

Applet, midlet, servlet dan kacang dari berbagai jenis dibangun dan kemudian memiliki metode siklus hidup yang memanggil mereka. Memanggil main adalah semua yang pernah dilakukan ke kelas utama, jadi tidak perlu suatu negara diadakan di objek yang disebut beberapa kali. Cukup normal untuk menyematkan utama pada kelas lain (meskipun bukan ide yang bagus), yang akan menghalangi penggunaan kelas untuk membuat objek utama.


5

Itu hanya sebuah konvensi, tetapi mungkin lebih nyaman daripada alternatifnya. Dengan main statis, yang perlu Anda ketahui untuk menjalankan program Java adalah nama dan lokasi kelas. Jika tidak statis, Anda juga harus tahu cara membuat instance kelas itu, atau mengharuskan kelas memiliki konstruktor kosong.


Itu bukan konvensi; itu bagian dari spesifikasi bahasa; runtime tidak akan mengenali kelas tanpa metode utama statis sebagai titik masuk yang valid.
Rob

2
Spek bahasa itu sendiri mengikuti konvensi. Tidak ada persyaratan aktual bagi perancang Java untuk memilih yang membutuhkan listrik statis. Namun, seperti yang dijelaskan Logan, alternatifnya lebih rumit.
David Arno

@ Davidvido Akan lebih masuk akal untuk mengatakan bahwa konvensi mengikuti spesifikasi bahasa.
Marquis of Lorne

5

Jika metode utama tidak statis, Anda perlu membuat objek kelas utama Anda dari luar program. Bagaimana Anda ingin melakukan itu?


5

Ketika Anda menjalankan Java Virtual Machine (JVM) dengan javaperintah,

java ClassName argument1 argument2 ...

Ketika Anda menjalankan aplikasi Anda, Anda menentukan nama kelasnya sebagai argumen untuk perintah java, seperti di atas

JVM mencoba untuk memanggil metode utama dari kelas yang Anda tentukan

—Pada poin ini, tidak ada objek kelas yang telah dibuat.

Mendeklarasikan mainsebagai statis allowsJVM ke invokeutama withoutmembuat instancekelas.

mari kembali ke perintah

ClassNameadalah command-line argumentke JVM yang memberitahu kelas mana yang harus dieksekusi. Mengikuti ClassName, Anda juga dapat menentukan list of Strings(dipisahkan oleh spasi) sebagai argumen baris perintah yang akan dilewati JVM ke aplikasi Anda. Argumen -seperti itu dapat digunakan untuk menentukan opsi (misalnya, nama file) untuk menjalankan aplikasi- ini adalah mengapa ada parameter yang disebut String[] argsdi utama

Referensi: Java ™ Cara Memprogram (Objek Awal), Edisi Kesepuluh


4

Baru-baru ini, pertanyaan serupa telah diposting di Programmers.SE

  • Mengapa metode utama statis di Java dan C #, daripada konstruktor?

    Mencari jawaban pasti dari sumber primer atau sekunder untuk alasan mengapa (terutama) Java dan C # memutuskan untuk memiliki metode statis sebagai titik masuknya - daripada merepresentasikan instance aplikasi dengan instance Applicationkelas, dengan entry point menjadi konstruktor yang sesuai?

TL; DR bagian dari jawaban yang diterima adalah,

Di Jawa, alasannya public static void main(String[] args)adalah itu

  1. Anak angsa ingin
  2. kode yang ditulis oleh seseorang yang berpengalaman dalam C (bukan di Jawa)
  3. untuk dieksekusi oleh seseorang yang terbiasa menjalankan PostScript di NeWS

http://i.stack.imgur.com/qcmzP.png

 
Untuk C #, alasannya hampir sama untuk berbicara. Desainer bahasa membuat sintaksis titik entri program tetap familier bagi programmer yang datang dari Jawa. Seperti yang dikatakan arsitek C #, Anders Hejlsberg ,

... pendekatan kami dengan C # hanyalah menawarkan alternatif ... ke pemrogram Java ...

...


3

Saya pikir kata kunci 'statis' menjadikan metode utama metode kelas, dan metode kelas hanya memiliki satu salinannya dan dapat dibagikan oleh semua, dan juga, tidak memerlukan objek untuk referensi. Jadi ketika kelas driver dikompilasi, metode utama dapat dipanggil. (Aku hanya di tingkat abjad java, maaf kalau aku salah)


Semua metode 'hanya memiliki satu salinannya'.
Marquis of Lorne

3

main () statis karena; pada saat itu dalam siklus hidup aplikasi, tumpukan aplikasi bersifat prosedural karena belum ada objek yang dipakai.

Ini adalah batu tulis yang bersih. Aplikasi Anda sedang berjalan pada titik ini, bahkan tanpa objek yang dideklarasikan (ingat, ada pola pengkodean DAN OO pengkodean). Anda, sebagai pengembang, mengubah aplikasi menjadi solusi berorientasi objek dengan membuat instance objek Anda dan bergantung pada kode yang dikompilasi di dalamnya.

Berorientasi objek bagus untuk jutaan alasan yang jelas. Namun, sudah tidak ada lagi hari ketika kebanyakan pengembang VB secara teratur menggunakan kata kunci seperti "goto" dalam kode mereka. "goto" adalah perintah prosedural dalam VB yang digantikan oleh pendahuluan OO: metode.

Anda juga bisa melihat titik masuk statis (utama) sebagai kebebasan murni. Seandainya Java cukup berbeda untuk membuat instance objek dan hanya menyajikan instance itu kepada Anda saat dijalankan, Anda tidak akan punya pilihan TAPI untuk menulis aplikasi prosedural. Meskipun mungkin terdengar tidak masuk akal untuk Jawa, mungkin ada banyak skenario yang membutuhkan pendekatan prosedural.

Ini mungkin jawaban yang sangat tidak jelas. Ingat, "kelas" hanya kumpulan kode yang saling terkait. "Instance" adalah generasi otonom yang terisolasi, hidup dan bernafas dari kelas itu.


7
Ini salah. Banyak objek yang dipakai sebelum maintercapai. Dan jika Anda menyertakan konstruktor statis di kelas yang berisi main, yang dieksekusi sebelumnya mainjuga.
Konrad Rudolph

2

Itu hanya sebuah konvensi. JVM tentu bisa menangani metode utama non-statis jika itu akan menjadi konvensi. Setelah semua, Anda dapat mendefinisikan penginisialisasi statis di kelas Anda, dan instantiate zillion objek sebelum sampai ke metode main () Anda.


2

Protoype public static void main(String[])adalah konvensi yang didefinisikan dalam JLS :

Metode utama harus dinyatakan publik, statis, dan tidak berlaku. Itu harus menentukan parameter formal (§8.4.1) yang tipe yang dinyatakan adalah larik String.

Dalam spesifikasi JVM 5.2. Start-up Virtual Machine dapat kita baca:

Mesin virtual Java memulai dengan membuat kelas awal, yang ditentukan dengan cara yang tergantung pada implementasi, menggunakan bootstrap class loader (§5.3.1). Mesin virtual Java kemudian menautkan kelas awal, menginisialisasi, dan memanggil metode kelas publik void main (String []) . Doa metode ini mendorong semua eksekusi lebih lanjut. Eksekusi instruksi mesin virtual Java yang merupakan metode utama dapat menyebabkan menghubungkan (dan akibatnya penciptaan) kelas dan antarmuka tambahan, serta permohonan metode tambahan.

Lucunya, dalam spesifikasi JVM itu tidak menyebutkan bahwa metode utama harus statis. Tetapi spec juga mengatakan bahwa mesin virtual Java melakukan 2 langkah sebelumnya:

Inisialisasi kelas atau antarmuka terdiri dari mengeksekusi kelas atau metode inisialisasi antarmuka.

Di 2.9. Metode khusus :

Sebuah metode kelas atau inisialisasi antarmuka didefinisikan:

Kelas atau antarmuka paling banyak memiliki satu metode inisialisasi kelas atau antarmuka dan diinisialisasi (§5.5) dengan memanggil metode itu. Metode inisialisasi kelas atau antarmuka memiliki nama khusus <clinit>, tidak mengambil argumen, dan tidak berlaku.

Dan metode inisialisasi kelas atau antarmuka berbeda dari metode inisialisasi contoh didefinisikan sebagai berikut:

Pada tingkat mesin virtual Java, setiap konstruktor yang ditulis dalam bahasa pemrograman Java (JLS §8.8) muncul sebagai metode inisialisasi instance yang memiliki nama khusus <init>.

Jadi JVM menginisialisasi metode inisialisasi kelas atau antarmuka dan bukan metode inisialisasi contoh yang sebenarnya adalah konstruktor. Jadi mereka tidak perlu menyebutkan bahwa metode utama harus statis dalam spesifikasi JVM karena tersirat oleh fakta bahwa tidak ada instance dibuat sebelum memanggil metode utama.


2

Kata publickunci adalah pengubah akses, yang memungkinkan programmer untuk mengontrol visibilitas anggota kelas. Ketika seorang anggota kelas didahului oleh public, maka anggota itu dapat diakses dengan kode di luar kelas yang dideklarasikan.

Kebalikan dari publicadalah private, yang mencegah anggota dari digunakan oleh kode yang ditentukan di luar kelasnya.

Pada kasus ini, main() harus dinyatakan sebagai public, karena harus dipanggil oleh kode di luar kelasnya ketika program dimulai.

Kata kunci static memungkinkan main()untuk dipanggil tanpa harus membuat instance instance kelas tertentu. Ini perlu karena main()dipanggil oleh Java interpreter sebelum objek dibuat.

Kata kunci voidhanya memberitahu kompiler yang main()tidak mengembalikan nilai.


1

Titik masuk sebenarnya ke aplikasi apa pun adalah metode statis. Jika bahasa Java mendukung metode instance sebagai "entry point", maka runtime akan perlu mengimplementasikannya secara internal sebagai metode statis yang membangun instance objek diikuti dengan memanggil metode instance.

Dengan itu, saya akan memeriksa alasan untuk memilih salah satu dari tiga opsi berikut:

  1. SEBUAH static void main() seperti yang kita lihat hari ini.
  2. Metode instan void main() disebut pada objek yang baru saja dibangun.
  3. Menggunakan konstruktor tipe sebagai titik masuk (misalnya, jika kelas entri dipanggil Program, maka eksekusi akan terdiri dari new Program()).

Kerusakan:

static void main()

  1. Memanggil konstruktor statis dari kelas melampirkan.
  2. Memanggil metode statis main().

void main()

  1. Memanggil konstruktor statis dari kelas melampirkan.
  2. Buat instance kelas tertutup dengan memanggil secara efektif new ClassName().
  3. Memanggil metode instance main().

new ClassName()

  1. Memanggil konstruktor statis dari kelas melampirkan.
  2. Membangun sebuah instance dari kelas (maka tidak melakukan apa-apa dengannya dan hanya mengembalikan).

Alasan:

Saya akan pergi dalam urutan terbalik untuk yang satu ini.

Perlu diingat bahwa salah satu tujuan desain Jawa adalah untuk menekankan (mengharuskan bila memungkinkan) praktik pemrograman berorientasi objek yang baik. Dalam konteks ini, konstruktor suatu objek menginisialisasi objek, tetapi seharusnya tidak bertanggung jawab atas perilaku objek. Oleh karena itu, spesifikasi yang memberikan titik masuknew ClassName() akan membingungkan situasi untuk pengembang Java baru dengan memaksa pengecualian pada desain konstruktor "ideal" pada setiap aplikasi.

Dengan membuat main()metode instan, masalah di atas tentu dipecahkan. Namun, itu menciptakan kompleksitas dengan mengharuskan spesifikasi untuk mendaftar tanda tangan konstruktor kelas entri serta tanda tanganmain() metode.

Singkatnya, menentukan suatu static void main()menciptakan spesifikasi dengan kompleksitas paling sedikit sambil mengikuti prinsip menempatkan perilaku ke dalam metode . Mempertimbangkan betapa mudahnya mengimplementasikan main()metode yang dengan sendirinya membangun turunan suatu kelas dan memanggil metode turunan, tidak ada keuntungan nyata untuk menetapkan main()sebagai metode turunan.


1
Ini hanya mengemis pertanyaan. Java membutuhkan pemuat aplikasi yang melakukan pengangkatan berat sebelum menelepon main. Dasar pemikiran Anda tentang mainmenjadi terlalu rumit untuk pemula tampaknya tidak dapat dipercaya. Bahkan, statis mainadalah sangat membingungkan untuk pemula, aku ragu konstruktor akan lebih. Anda mengatakan "konstruktor seharusnya tidak bertanggung jawab atas perilaku objek". Ini kedengarannya menarik tetapi saya tidak yakin saya akan setuju. Kenapa tidak? Apa yang mencegah ini?
Konrad Rudolph

1

statis - Ketika JVM membuat panggilan ke metode utama tidak ada objek yang ada untuk kelas yang dipanggil karena itu harus memiliki metode statis untuk memungkinkan doa dari kelas.


1

Saya tidak tahu apakah JVM memanggil metode utama sebelum objek dipakai ... Tapi ada alasan yang jauh lebih kuat mengapa metode main () statis ... Ketika JVM memanggil metode utama kelas (katakanlah , Orang). itu memanggilnya dengan " Person.main () ". Anda lihat, JVM memanggilnya dengan nama kelas. Itulah sebabnya metode main () seharusnya bersifat statis dan umum sehingga dapat diakses oleh JVM.

Semoga ini bisa membantu. Jika ya, beri tahu saya dengan berkomentar.


0

Metode statis tidak memerlukan objek apa pun. Ini berjalan langsung sehingga berjalan utama langsung.


0

Kata kunci statis dalam metode utama digunakan karena tidak ada instantiasi yang terjadi dalam metode utama. Tetapi objek dibangun daripada doa sebagai akibatnya kita menggunakan kata kunci statis dalam metode utama. Dalam konteks jvm, memori dibuat ketika kelas memuat ke dalamnya. Dan semua anggota statis hadir dalam memori itu. jika kita membuat statis utama sekarang itu akan ada dalam memori dan dapat diakses ke jvm (class.main (..)) sehingga kita dapat memanggil metode utama tanpa perlu bahkan perlu untuk heap telah dibuat.


0

Itu hanya sebuah konvensi seperti yang dapat kita lihat di sini:

Metode harus dinyatakan publik dan statis , tidak boleh mengembalikan nilai apa pun, dan harus menerima array String sebagai parameter. Secara default, argumen non-opsi pertama adalah nama kelas yang akan dipanggil. Nama kelas yang sepenuhnya memenuhi syarat harus digunakan. Jika opsi -jar ditentukan, argumen non-opsi pertama adalah nama arsip JAR yang berisi file kelas dan sumber daya untuk aplikasi, dengan kelas startup ditunjukkan oleh header manifes Main-Class.

http://docs.oracle.com/javase/1.4.2/docs/tooldocs/windows/java.html#description


Aturan bahasa, maksud Anda.
Marquis of Lorne


0

Pada dasarnya kami menjadikan ANGGOTA DATA dan FUNGSI ANGGOTA sebagai STATIC yang tidak melakukan tugas apa pun yang terkait dengan suatu objek. Dan dalam hal metode utama, kita menjadikannya sebagai STATIC karena tidak ada hubungannya dengan objek, karena metode utama selalu dijalankan apakah kita membuat objek atau tidak.


0

Metode apa pun yang dinyatakan sebagai statis di Jawa adalah milik kelas itu sendiri. Sekali lagi metode statis kelas tertentu hanya dapat diakses dengan merujuk ke kelas sukaClass_name.method_name();

Jadi suatu kelas tidak perlu dipakai sebelum mengakses metode statis.

Jadi metode main () dideklarasikan staticsedemikian sehingga dapat diakses tanpa membuat objek dari kelas itu.

Karena kita menyimpan program dengan nama kelas di mana metode utama hadir (atau dari mana program harus memulai pelaksanaannya, berlaku untuk kelas tanpa main()metode () (Tingkat Mahir)). Jadi dengan cara yang disebutkan di atas:

Class_name.method_name();

metode utama dapat diakses.

Singkatnya ketika program dikompilasi, ia mencari main()metode yang memiliki Stringargumen seperti: main(String args[])dalam kelas yang disebutkan (yaitu dengan nama program), dan karena pada awalnya ia tidak memiliki ruang untuk membuat instance kelas itu, jadi main () Metode ini dinyatakan sebagai statis.


Itu terjadi ketika program dijalankan, tidak dikompilasi.
Marquis of Lorne

0

Dari java.sun.com (ada informasi lebih lanjut di situs):

Metode utama adalah statis untuk memberikan Java VM interpreter cara untuk memulai kelas tanpa membuat turunan dari kelas kontrol terlebih dahulu. Contoh kelas kontrol dibuat dalam metode utama setelah program dimulai.

Pemahaman saya selalu sederhana bahwa metode utama, seperti metode statis apa pun, dapat dipanggil tanpa membuat turunan dari kelas terkait, yang memungkinkannya untuk berjalan sebelum hal lain dalam program. Jika tidak statis, Anda harus membuat instance objek sebelum memanggilnya - yang menciptakan masalah 'ayam dan telur', karena metode utama umumnya adalah apa yang Anda gunakan untuk instantiate objek pada awal program.


Tetapi itu tidak berjalan "sebelum hal lain dalam program". Seluruh argumen adalah kekeliruan, dan terlebih lagi, ini bukan jawaban pertama yang menyebutkannya, atau bahkan yang kedua atau ketiga.
Konrad Rudolph

Saya minta maaf karena jawaban saya mengulangi apa yang dikatakan orang lain; Saya hanya menjawab yang terbaik dari pemahaman saya dan dari apa yang dapat saya temukan online. Dari hasil yang saya lihat tidak ada alasan lain mengapa metode utamanya statis; kecuali ada satu yang sangat tersembunyi di suatu tempat mungkin itulah satu-satunya jawaban. Pemahaman saya tentang Java cukup mendasar, tetapi saya telah mendengar alasan di atas (dari profesor, buku teks, dll) dan tidak pernah ada yang lain.
Jesse M

@ Jesse M Komentar Anda hanya masuk akal jika Anda bahkan tidak mempertimbangkan membaca jawaban lain terlebih dahulu. Ngomong-ngomong bukan hal yang terlalu jauh untuk dilakukan. Seperti yang Anda sebutkan, pemahaman Anda cukup mendasar sehingga sangat mungkin orang lain sudah menjawab pertanyaan dengan lebih kompeten. Dan komentar Anda tampaknya menjadi rasionalisasi untuk membuat jawaban Anda terlihat lebih baik. Ini adalah klaim luar biasa bahwa Anda memiliki buku teks dan profesor Java yang memikirkan apa yang Anda klaim dan terus terang saya tidak percaya mereka melakukannya. (Ada referensi?)
LeoR

1
@KonradRudolph Komentar teratas sepertinya cukup masuk akal. main () digunakan sebagai titik masuk ke program dan ada beberapa referensi di situs web Java yang mengatakan bahwa itu seharusnya mirip dengan bagaimana C / C ++ memiliki fungsi main (). Karena Java adalah semua Objek, itu harus statis untuk menghindari instantiasi objek. Setelah itu statis juga memungkinkannya dimuat dan dieksekusi ke JVM saat runtime. Saya hanya memuntahkan jawaban sebelumnya, tetapi saya ingin tahu apa yang Anda anggap sebagai jawaban yang memuaskan. Saya pikir yang terbaik yang akan Anda dapatkan adalah "Begitulah yang mereka inginkan". Ingat tanggal pembuatan Java.
trevor-e

1
@Jesse Spot-on. Sangat mungkin bahwa itu hanya masalah konvensi (meskipun saya berharap tidak, itu akan menjadi jawaban yang membosankan). Ketertarikan asli saya pada pertanyaan ini adalah karena saya berpikir bahwa menggunakan contoh yang tepat untuk mewakili objek "menjalankan aplikasi", dan memiliki titik masuk menjadi metode (atau konstruktor) dari kelas ini akan menjadi desain yang jauh lebih jelas, karena Java dirancang untuk menjadi berorientasi objek dari get-pergi, dan karena benda-benda yang tampaknya analog (benang, melalui Runnable) di Jawa melakukan menggunakan desain ini. Mengapa pengecualian (jelas) di sini?
Konrad Rudolph
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.