Apakah utama Java identifier yang valid?

288

Salah satu anak saya mengambil Jawa di sekolah menengah dan melakukan ini di salah satu tesnya:

Manakah dari berikut ini yang merupakan pengidentifikasi yang valid di Java?

Sebuah. 123java
b. main
c. java1234
d. {abce
e. )whoot

Dia menjawab b dan salah.

Saya melihat pertanyaan dan berpendapat bahwa itu main adalah pengidentifikasi yang valid dan itu seharusnya benar.

Kami melihat pada spec Java untuk pengidentifikasi dan memperkuat titik itu. Kami juga menulis contoh program yang memiliki variabel yang dipanggil main, serta metode. Dia membuat bantahan tertulis yang menyertakan referensi dokumentasi Java, program tes dan guru mengabaikannya dan mengatakan jawabannya masih salah.

Apakah mainpengidentifikasi yang valid?

Gary Bak
sumber
12
Itu selalu membuat saya sedih melihat seorang guru begitu tidak aman sehingga dia takut belajar sesuatu yang baru dan mengakui kesalahan.
Ryan Lundy
saya kira itu. tetapi Anda benar-benar tidak boleh menggunakannya sebagai nama variabel / metode (kasus yang jelas meskipun), jadi jika guru mencoba mengebor titik rumah untuk memikirkan - terutama dalam hal ini - nama metode maka saya dapat melihat / nya maksudnya.
bharal
3
Apakah pertanyaan ini benar-benar bertanya, apakah guru putra Anda melakukan pekerjaannya dengan benar? Saya melihat dua pengidentifikasi Java yang valid. Jadi jawabannya adalah 'b' DAN 'c'. Jadi gurunya benar. Atau apakah saya melewatkan sesuatu? Bagaimana ini bisa menjadi pertanyaan SO? Menilai tentang seseorang yang bahkan bukan bagian dari komunitas ...
jschnasse
1
Ini adalah pertanyaan tentang guru, bukan tentang java.
ACV
1
Kasus lain dari kasus "ditipu oleh pertanyaan tipuan Anda sendiri"; guru benar-benar harus setidaknya melirik spec bahasa sebelum mencoba menulis pertanyaan ujian seperti ini.
jrh

Jawaban:

253
public class J {
    public static void main(String[] args)
    {
        String main = "The character sequence \"main\" is an identifier, not a keyword or reserved word.";
        System.out.println(main);
    }
}

Ini mengkompilasi, dan ketika dieksekusi, memancarkan output ini:

The character sequence "main" is an identifier, not a keyword or reserved word.

Urutan karakter mainadalah pengidentifikasi, bukan kata kunci atau kata yang dipesan.

Bagian yang relevan dari JLS adalah 3.8 :

Sebuah identifier adalah urutan terbatas-panjang huruf Jawa dan angka Jawa , yang pertama harus huruf Jawa .

Identifier:

    IdentifierChars tetapi bukan Kata Kunci atau BooleanLiteral atau NullLiteral

IdentifierChars:

    JavaLetter {JavaLetterOrDigit}

JavaLetter:

    setiap karakter Unicode yang merupakan "surat Java"

JavaLetterOrDigit:

    setiap karakter Unicode yang merupakan "Java letter-or-digit"

Urutan karakter mainsesuai dengan deskripsi di atas dan tidak ada dalam daftar kata kunci di Bagian 3.9 .

(Urutan karakter java1234juga merupakan pengidentifikasi, untuk alasan yang sama.)

rgettman
sumber
25
@ Locklock. Pertanyaannya adalah worded sehingga hanya satu pilihan yang bisa benar. Namun, kedua pilihan b dan c memenuhi kondisi pertanyaan, tidak konsisten dengan pilihan yang tersirat. Ini membuat anak OP memilih antara jawaban yang benar adalah satu-satunya jawaban yang menurut guru itu benar.
rgettman
@rgettman saya membaca " Manakah dari yang berikut ... " yang memungkinkan lebih dari satu pilihan, yang mana " b dan c " akan menjadi respons yang valid.
TripeHound
6
@ TripeHound "adalah pengidentifikasi yang valid" adalah tunggal dan menuntut 1 jawaban. Bandingkan dengan "adalah pengidentifikasi yang valid"
Berikan 411
2
Anda bisa membuat kelas mainjuga;)
Peter Lawrey
97

main adalah pengidentifikasi java yang valid, dan guru salah.

Dokumentasi yang relevan ada di Spesifikasi Bahasa Jawa, di sini:

Bab 3. "Struktur Leksikal", bagian 3.8. "Pengidentifikasi":

https://docs.oracle.com/javase/specs/jls/se10/html/jls-3.html#jls-3.8

Ia mengatakan:

Identifier adalah urutan panjang tak terbatas dari huruf Java dan digit Java, yang pertama harus berupa huruf Java ... Identifier tidak boleh memiliki ejaan yang sama (urutan karakter Unicode) sebagai kata kunci (§3.9), boolean literal ( §3.10.3), atau nol literal (§3.10.7), atau kesalahan waktu kompilasi terjadi.

Yang berarti Anda dapat membuktikan bahwa itu adalah pengidentifikasi yang valid baik dengan:

  • mencarinya di daftar kata kunci java (petunjuk: Anda tidak akan menemukannya di sana!) atau hanya dengan
  • menggunakannya sebagai pengidentifikasi dan mengamati bahwa tidak ada kesalahan waktu kompilasi terjadi.
Mike Nakis
sumber
1
Bisakah Anda mengutip dan mengejanya lebih eksplisit?
zero298
36
tidak, karena ini adalah seluruh bagian. Jika guru berpikir bahwa bagian ini membuat semacam pengecualian untuk 'utama', itu adalah guru yang harus menunjukkan di mana dikatakan demikian.
Mike Nakis
76

Seperti yang dinyatakan jawaban lainnya

mainadalah pengidentifikasi Java yang valid , juga java1234.

Saya kira yang membingungkan berasal dari fakta bahwa main(String[])metode ini sering digunakan sebagai titik masuk oleh JVM 1 . Namun, itu tidak berarti bahwa token mainitu sendiri tidak dapat digunakan sebagai pengidentifikasi 2 .

Spesifikasi mengatakan demikian, dan deklarasi berikut ini juga valid:

  • Bidang:

    private int main;
  • Variabel lokal:

    String main = "";
  • Sebuah metode:

    private void main() { ... }
  • Kelas (meskipun nama kelas yang dimulai dengan huruf kecil tidak disarankan):

    public class main { ... }
  • Sebuah paket:

    package main;

1: Seperti disebutkan dalam komentar, spesifikasi JVM itu sendiri tidak mengamanatkan metode tertentu sebagai titik masuk, tetapi alat yang banyak digunakan javasering menggunakan metode seperti itu sebagai titik masuk.
2: Saya biasanya menghindari membuat metode utama selain main(String[]).

MC Emperor
sumber
22
"Saya kira yang membingungkan berasal dari fakta bahwa metode utama (String []) digunakan sebagai titik masuk untuk JVM." mainbukan titik masuk untuk JVM. Ini adalah titik masuk yang javadigunakan alat untuk menjalankan aplikasi. Alat lain (wadah servlet, misalnya) menggunakan titik masuk lainnya.
TJ Crowder
27
yang bahkan lebih ironis, karena bahkan dalam "entry-point-context" utama SUDAH ADALAH pengidentifikasi yang valid. Jadi, bahkan jika Anda dapat menahannya benar-benar membuktikan OP benar
Hobbamok
@TJCrowder Terima kasih, saya sudah memasukkan itu dalam jawabannya.
MC Emperor
1
@Hobbamok Anda sepertinya bingung tentang konsep dasar Java, yang mungkin menjelaskan mengapa Anda mengajar di sekolah dan tidak berlatih adalah jawaban yang muncul di benak Anda
rath
4
The javaalat tidak memerlukan main(String[])metode jika kelas utama meluas javafx.application.Application .
VGR
65

Ini mengkompilasi dengan baik pada Java 1.8 ...

public class main {

    public String main = "main"; 

    public void main(String main) {
        System.out.println("This object is an instance of the class " + this.getClass().getCanonicalName());
        System.out.println("The value of the argument \"main\" for this call to the method \"main(String main)\" is " + main);
        System.out.println("The value of the field \"main\" is " + this.main);
    }

    public static void main(String[] args) {
        main main = new main();
        main.main(main.main + main.main);
    }
}

... dan ketika dieksekusi menghasilkan output:

This object is an instance of the class main
The value of the argument "main" for this call to the method "main(String main)" is mainmain
The value of the field "main" is main
MichaelK
sumber
5
Apakah mungkin menambahkan static mainmetode lain dengan parameter yang berbeda?
jpmc26
6
@ jpmc26 Cobalah dan beri tahu kami perkembangannya. :)
MichaelK
1
Nah itu banyak induk
MC Kaisar
4
@MCEmperor Ya, itulah argumen utama saya untuk jawaban saya. ;)
MichaelK
3
Anda lupa menambahkan package main;!
Solomon Ucko
45

Saya melemparkan semua yang saya bisa ke sana, dan tampaknya berhasil. Saya akan mengatakan utama adalah pengidentifikasi yang valid.

package main;

public class main {

    static main main;
    String Main;

    main(String main) {
        Main = main;
    }

    main(main main) {
        System.out.println(main.Main);
    }

    main main(main main) {
        return new main(main);
    }

    public static void main(main...Main) {
        main:
        for (main main : Main) {
            main = (main instanceof Main) ? new main(main): main.main(main);
            break main;
        }
    }

    public static void main(String[] args) {
        main = new main("main");
        main.main(main, main);
        main = main.new Main(main) {
            main main(main main) {
                return ((Main)main).main();
            }
        };
        main.main(main);
        main.main(main,main);
    }

    abstract class Main extends main {
        Main(main main) {
            super("main");
        }

        main main() {
            main.Main = "Main";
            return main;
        }
    }
}
18107
sumber
2
Saya suka itu. Coba 'grep -o main.java utama | wc-l '
Gary Bak
3
Kode itu agak mengingatkan saya pada bahasa pemrograman "ook" ^^ Hampir setiap kata dalam kode ini adalah "utama" ...
Florian Bach
public static void main(main...Main)( kehilangan ruang ) tidak bisa bekerja, bukan?
GeroldBroser mengembalikan Monica
3
Saya merasa seperti saya yang utama itu.
Ross Presser
1
@GeroldBroser Itu lebih bersih, tetapi tidak sepenuhnya diperlukan: spasi putih di antara token dalam banyak kasus bersifat opsional, mereka hanya diperlukan jika gabungan dua token berikutnya juga valid.
MC Emperor
44

Bagaimana maintidak bisa digunakan sebagai pengidentifikasi sementara itu digunakan sebagai pengidentifikasi untuk mendeklarasikan metode "utama"?

Untuk ungkapan klasik seperti itu:

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

main bukan kata kunci dan mungkin tidak akan pernah menjadi kata kunci di Jawa karena alasan kompatibilitas retro yang jelas.


Tentang pertanyaan, apakah mainpengidentifikasi yang baik?

Pertama: valid untuk kompiler tidak berarti selalu baik.
Misalnya java1234opsi yang diusulkan juga merupakan pengidentifikasi yang valid tetapi itu harus benar-benar dihindari.

mainmemiliki arti yang sangat khusus dan penting: digunakan sebagai metode titik masuk kelas dan guci yang dieksekusi oleh javabaris perintah.
Menggunakan mainuntuk nama metode yang tidak memenuhi kriteria yang akan digunakan oleh javabaris perintah akan hanya menyesatkan saat menggunakannya sebagai nama variabel atau nama kelas bisa masuk akal.
Misalnya mendefinisikan kelas yang mewakili titik masuk aplikasi sebagai Mainkelas aplikasi dapat diterima dan menggunakannya sebagai nama variabel juga seperti:

public class Main {

  public static void main(String args[]){
     Main main = new Main();
     // ...
  }      

}

Secara umum, di Jawa, banyak karakter atau "kata" dianggap sebagai pengidentifikasi yang valid untuk kompiler tetapi sangat tidak disarankan untuk digunakan dalam kode klien (tetapi kode yang dihasilkan dapat melakukan hal itu: kelas bersarang misalnya) tidak dapat dibaca dan / atau benar-benar menyesatkan.

Misalnya ini bisa valid untuk kompiler:

public class Object { // 1
    public void foo() {
       ...
    }
}

public class BadChosenIdentifier {

    public static void main() { // 2
        new BadChosenIdentifier().toString(new Object());  
    }

    public void toString(Object java1234) { // 3, 4
        String _result$ = java1234 + " -> to avoid"; // 4
        System.out.println(_result$);
    }    
}

Tapi kami tidak mau:

  • memberi nama Objectkelas kami karena ini didefinisikan dalam java.lang(1).
  • memberi nama metode main()jika tidak memenuhi kriteria yang akan digunakan oleh javabaris perintah (2).
  • untuk membebani Object.toString()metode (3).
  • untuk memberi nama variabel kita dengan _, $atau karakter mengejutkan / tidak berarti yang bertentangan dengan konvensi penamaan bersama (4).
davidxxx
sumber
7
Sekadar diketahui, mainbisa berupa kata kunci yang hanya dapat digunakan sebagai nama untuk metode statis dengan tanda tangan yang sesuai (atau apa pun). Perhatikan bahwa panggilan kelas super digunakan superdengan cara yang membuatnya terlihat seperti pengidentifikasi: super(foo);dan super.foo, tetapi superADALAH kata kunci (dan sebelum obat generik ditambahkan, ini adalah satu-satunya cara untuk menggunakannya (yang dapat saya ingat)).
jaxad0127
@ jaxad0127 Poin menarik tapi saya tidak sepenuhnya setuju. Sebenarnya itu TIDAK dan di masa depan mungkin tidak karena alasan kompatibilitas. Jika Anda didefinisikan mainsebagai kata kunci dalam versi baru java, itu berarti bahwa setiap kode yang menggunakan utama sebagai nama metode (atau nama anggota apa pun) tidak akan dikompilasi lagi. Penggunaan superdalam generik tidak memiliki efek samping dalam kode yang ada karena generik tidak ada saat ini.
davidxxx
2
Saya hanya bermaksud bahwa itu BISA telah dilakukan sebagai kata kunci. Hanya karena terlihat seperti pengenal, bukan berarti harus seperti itu.
jaxad0127
2
Saya berpendapat bahwa mainini masih merupakan pengidentifikasi yang lebih baik daripada java1234. Menggunakannya untuk metode "biasa" akan menyesatkan, tetapi saya tidak akan memiliki masalah dalam penamaan variabel main, jika itu sebenarnya sesuatu yang utama dalam metode saya. java1234hanya mengerikan, nama harus deskriptif ...
AJPerez
1
"Tentang pertanyaan, apakah main pengidentifikasi yang baik?" Tergantung. Saya mungkin tidak akan menatap variabel bernama mainjika fungsi yang saya lihat melakukan sesuatu dengan data utama air. Aku akan muntah jika saya pernah melihat java1234dalam kode produksi (dan berdoa tidak ada 1233 variabel lain dengan awalan java).
jpmc26
40

Apakah itu pengidentifikasi yang valid? Iya.

Apakah ini pengenal yang baik? Tidak jika Anda menggunakannya untuk apa pun selain metode yang dimulai pada peluncuran JVM.

Apakah pengidentifikasi lain yang valid terdaftar? Iya.

Apakah instruksi tes mengatakan untuk memilih jawaban terbaik?

pengguna1423956
sumber
7
Setuju - pilihan ganda seperti ini adalah tentang memilih jawaban yang benar 'terbaik' ketika ada banyak. Namun, itu tidak menjadikan ini pertanyaan pilihan ganda yang bagus dan saya pikir berbicara dengan guru tentang itu adalah hal yang tepat untuk dilakukan.
Shadow
19
@Shadow Ini adalah kursus pemrograman. Ambiguitas pada pertanyaan tentang sesuatu yang ditentukan dengan tata bahasa matematika formal tidak dapat ditoleransi. Berbicara secara tegas terhadap standar itu (yang tersirat oleh " valid "), kedua jawaban sama benarnya. Saya bisa membayangkan jauh lebih banyak kasus di mana mainpengidentifikasi dapat ditoleransi daripada yang bisa saya java1234lakukan. Pertimbangkan, misalnya, basis kode yang bekerja dengan data pasokan air (saluran air).
jpmc26
5
Di sisi lain, java1234 bau ke surga yang tinggi sebagai pengidentifikasi.
Yosua
4
"pilih jawaban terbaik" tidak berarti "mencari tahu ketika guru tidak tahu apa yang mereka bicarakan dan menebak jawaban buruk yang mereka pikirkan." main tidak hanya pengidentifikasi yang valid , itu pengenal yang sangat penting karena setiap aplikasi Java memiliki metode utama, dan metode diberi nama dengan pengidentifikasi.
fluffysheap
2
Saya menemukan jawaban ini sangat beralasan dan saya berharap saya bisa memilihnya lebih dari satu kali. Tampaknya Anda mencoba mengambil sisi dengan cara apa pun dan tidak mempertimbangkan gambaran yang lebih luas. mainadalah pengidentifikasi sempurna di mana saja di luar domain sempit aplikasi Java biasa. Itu bisa berupa nama bidang dalam kelas yang mewakili set menu. Atau <main>bagian dari dokumen dalam pembuat HTML. java1234, di sisi lain, hampir sama mengerikannya dengan pengidentifikasi.
toniedzwiedz
29
public class Main {
    private static String main;
    public static void main(String[] main) {
        Main.main = main[0];
        new Main().main(Main.main);
    }
    private void main(String main) {
        System.out.println(main);
    }
}
ililit
sumber
7

Guru itu membuat kesalahan kecil dalam mengasumsikan utama bukan pengidentifikasi yang valid atau hanya mengutarakan pertanyaan yang salah. Dia mungkin bermaksud mengatakan "pengidentifikasi yang baik".
Tetapi mengabaikan argumen putra Anda dan dengan demikian menghambat pendekatan ilmiahnya memeriksa literatur yang relevan (spesifikasi Java) dan melakukan percobaan (menulis program sampel) adalah kebalikan dari apa yang seharusnya dilakukan oleh seorang guru.

pengguna82593
sumber
1
Seperti dicatat pada jawaban lain, mainjauh lebih sering pengidentifikasi "baik" daripada sebelumnya java1234. Bahkan di sana, gurunya salah. ;)
jpmc26
5

Keduanya maindan java123merupakan pengidentifikasi yang valid , utama bukan kata kunci yang dilindungi undang-undang sehingga sangat dapat diterima untuk digunakan, sejauh pengujian berlangsung, Anda setidaknya harus mendapatkan poin atau setengah poin.

shavar
sumber
5
  1. Harus satu kata. Itu spasi tidak diizinkan.

    Contoh: mangoprice valid tetapi harga mangga tidak valid.

  2. Harus dimulai dengan huruf (alfabet) atau garis bawah atau simbol $.

    Contoh: harga, _ harga dan $ harga adalah pengidentifikasi yang valid.

  3. Seharusnya bukan kata kunci Java karena kata kunci membawa arti khusus ke kompiler.

    Contoh: kelas atau batal dll.

  4. Seharusnya tidak dimulai dengan angka tetapi digit bisa di tengah atau di akhir.

    Contoh: 5mangoescost tidak valid dan mango5cost dan mangocost5 valid.

  5. Panjang pengidentifikasi di Jawa bisa 65.535 karakter dan semuanya signifikan. Pengidentifikasi peka terhadap huruf besar-kecil. Baik itu mangga maupun mangga diperlakukan berbeda. Dapat berisi semua huruf besar atau huruf kecil atau campuran.

IDENTIFIER : mereka adalah nama kelas, nama metode, nama variabel ...

Sebagai kata kunci bukan kata yang dilindungi undang-undang dan menurut penjelasan di atas untuk mendefinisikan kata pengenal, kata kunci adalah pengidentifikasi yang valid dan java1234 juga. Opsi penahanan tidak valid karena penjelasan di atas.

subhashis
sumber