Chính có phải là một định danh Java hợp lệ không?


288

Một trong những đứa trẻ của tôi đang học Java ở trường trung học và đã làm điều này trong một trong những bài kiểm tra của mình:

Điều nào sau đây là một định danh hợp lệ trong Java?

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

Anh trả lời b và nhận sai.

Tôi đã xem xét câu hỏi và lập luận rằng đó main một định danh hợp lệ và nó đáng lẽ phải đúng.

Chúng tôi đã xem xét thông số kỹ thuật Java cho các định danh và nó củng cố quan điểm đó. Chúng tôi cũng đã viết một chương trình mẫu có một biến được gọi main, cũng như một phương thức. Ông đã tạo ra một phản bác bằng văn bản bao gồm tài liệu tham khảo Java, chương trình kiểm tra và giáo viên đã bỏ qua nó và nói rằng câu trả lời vẫn không chính xác.

mainmột định danh hợp lệ?


12
Nó luôn làm tôi buồn khi thấy một giáo viên không an tâm đến nỗi anh ấy / cô ấy sợ phải học một cái gì đó mới và thừa nhận một sai lầm.
Ryan Lundy

tôi đoán là vậy nhưng bạn thực sự không nên sử dụng nó như một tên biến / phương thức (trường hợp rõ ràng mặc dù), vì vậy nếu giáo viên đang cố gắng khoan điểm nhà để suy nghĩ kỹ - đặc biệt là trong trường hợp này - tên phương thức thì tôi có thể thấy / quan điểm của cô ấy.
bharal

3
Câu hỏi này có thực sự hỏi không, liệu giáo viên của con trai bạn có thực hiện đúng công việc của mình không? Tôi thấy hai định danh Java hợp lệ. Vì vậy, câu trả lời là 'b' 'c'. Vậy là giáo viên đúng. Hay tôi đang thiếu một cái gì đó? Làm thế nào đây có thể là một câu hỏi SO? Đánh giá về một số người thậm chí không phải là một phần của cộng đồng ...
jschnasse

1
Đây là một câu hỏi về giáo viên, không phải về java.
ACV

1
Một trong những trường hợp "bị lừa bởi câu hỏi lừa của chính bạn"; giáo viên thực sự nên ít nhất liếc qua thông số ngôn ngữ trước khi cố gắng viết một câu hỏi thi như thế này.
jrh

Câu trả lời:


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);
    }
}

Điều này biên dịch và khi được thực thi, sẽ phát ra đầu ra này:

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

Chuỗi ký tự mainlà một định danh, không phải là một từ khóa hoặc từ dành riêng.

Phần có liên quan của JLS là 3,8 :

Một định danh là một chuỗi các chữ cái Javachữ số Java có độ dài không giới hạn , đầu tiên phải là một chữ cái Java .

Định danh:

    Mã định danh nhưng không phải là từ khóa hoặc BooleanLiteral hoặc NullLiteral

Mã định danh:

    JavaLetter {JavaLetterOrDigit}

JavaLetter:

    bất kỳ ký tự Unicode nào là "chữ Java"

JavaLetterOrDigit:

    bất kỳ ký tự Unicode nào là "chữ cái hoặc chữ số Java"

Chuỗi ký tự mainphù hợp với mô tả ở trên và không có trong danh sách từ khóa trong Phần 3.9 .

(Chuỗi ký tự java1234cũng là một định danh, vì những lý do tương tự.)


25
@Clockwork Câu hỏi được diễn đạt sao cho chỉ có một lựa chọn có thể đúng. Tuy nhiên, cả hai lựa chọn bc đều thỏa mãn điều kiện của câu hỏi, không phù hợp với lựa chọn ngụ ý. Điều này khiến cho con của OP phải lựa chọn giữa câu trả lời đúng là câu duy nhất mà giáo viên nghĩ là đúng.
rgettman

@rgettman Tôi đọc " Điều nào sau đây ... " khi cho phép nhiều lần lựa chọn, trong đó " b và c " sẽ là phản hồi hợp lệ.
TripeHound

6
@TripeHound "là một định danh hợp lệ" là số ít và yêu cầu chính xác 1 câu trả lời. So sánh nó với "là các định danh hợp lệ"
Gimme the 411

2
Bạn cũng có thể tham gia lớp học main;)
Peter Lawrey

97

main là một định danh java hợp lệ và giáo viên đã sai.

Các tài liệu liên quan có trong Đặc tả ngôn ngữ Java, ngay tại đây:

Chương 3. "Cấu trúc từ điển", phần 3.8. "Định danh":

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

Nó nói rằng:

Mã định danh là một chuỗi các chữ cái Java và chữ số Java có độ dài không giới hạn, đầu tiên phải là một chữ cái Java ... Một mã định danh không thể có cùng một cách viết (chuỗi ký tự Unicode) như một từ khóa (§3.9), boolean bằng chữ ( §3.10.3) hoặc bằng chữ rỗng (§3.10.7) hoặc xảy ra lỗi thời gian biên dịch.

Điều đó có nghĩa là bạn có thể chứng minh rằng đó là một định danh hợp lệ bằng cách:

  • tìm kiếm nó trong danh sách các từ khóa java (gợi ý: bạn sẽ không tìm thấy nó ở đó!) hoặc đơn giản là
  • sử dụng nó như một định danh và quan sát rằng không có lỗi thời gian biên dịch xảy ra.

1
Bạn có thể trích dẫn và đánh vần nó rõ ràng hơn?
zero298

36
không, bởi vì nó là toàn bộ phần Nếu giáo viên nghĩ rằng phần này tạo ra một số ngoại lệ cho 'chính', thì đó là giáo viên phải chỉ ra nơi nó nói như vậy.
Mike Nakis

76

Như các câu trả lời khác

mainlà một định danh Java hợp lệ , cũng như java1234.

Tôi đoán sự khó hiểu xuất phát từ thực tế là main(String[])phương thức này thường được sử dụng làm điểm vào của JVM 1 . Tuy nhiên, điều đó không có nghĩa là mã thông báo mainkhông thể được sử dụng làm định danh 2 .

Thông số kỹ thuật nói như vậy và các tuyên bố sau đây cũng hợp lệ:

  • Một lĩnh vực:

    private int main;
  • Một biến cục bộ:

    String main = "";
  • Một phương pháp:

    private void main() { ... }
  • Một lớp (mặc dù tên lớp bắt đầu bằng chữ thường không được khuyến khích):

    public class main { ... }
  • Một gói:

    package main;

1: Như đã lưu ý trong các nhận xét, bản thân đặc tả JVM không bắt buộc bất kỳ phương thức cụ thể nào làm điểm vào, nhưng javacông cụ được sử dụng rộng rãi thường sử dụng một phương thức như điểm nhập cảnh.
2: Tôi thường sẽ tránh tạo ra một phương thức chính khác hơn là main(String[]).


22
"Tôi đoán sự khó hiểu xuất phát từ thực tế là phương thức chính (Chuỗi []) được sử dụng làm điểm vào cho JVM." mainkhông phải là điểm vào cho JVM. Đó là điểm vào mà javacông cụ sử dụng để chạy các ứng dụng. Các công cụ khác (ví dụ như các thùng chứa servlet) sử dụng các điểm vào khác.
TJ Crowder

27
điều này thậm chí còn mỉa mai hơn, bởi vì ngay cả trong "bối cảnh điểm nhập cảnh" chính ALREADY LÀ một định danh hợp lệ. Vì vậy, ngay cả trường hợp bạn có thể chống lại nó thực sự chứng minh OP đúng
Hobbamok

@TJCrowder Cảm ơn, tôi đã đưa nó vào câu trả lời.
MC Hoàng đế

1
@Hobbamok Bạn tỏ ra lúng túng về các khái niệm cơ bản Java, mà có lẽ giải thích lý do tại sao bạn dạy nó trong một trường và không thực hành là câu trả lời mà nói đến cái tâm
Rath

4
Công javacụ không yêu cầu một main(String[])phương thức nếu lớp chính mở rộng javafx.application.Application .
VGR

65

Điều này biên dịch tốt trên 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);
    }
}

... và khi được thực thi sẽ tạo đầu ra:

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

5
Có thể thêm một static mainphương thức khác với các tham số khác nhau?
jpmc26

6
@ jpmc26 Hãy dùng thử và cho chúng tôi biết nó đã đi như thế nào. :)
MichaelK

1
Vâng , đó là rất nhiều chính
MC Hoàng đế

4
@MCEmaoh Vâng, đó là lý lẽ chính cho câu trả lời của tôi. ;)
MichaelK

3
Bạn quên thêm package main;!
Solomon Ucko

45

Tôi đã ném mọi thứ tôi có thể vào nó, và nó dường như hoạt động. Tôi muốn nói chính là một định danh hợp lệ.

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;
        }
    }
}

2
Tôi thích nó. Hãy thử một 'grep -o main main.java | wc -l '
Gary Bak

3
Mã đó làm tôi nhớ đến ngôn ngữ lập trình "ook" ^^ Hầu như mọi từ trong mã này là "chính" ...
Florian Bach

public static void main(main...Main)( thiếu một không gian ) không thể làm việc, phải không?
GeroldBroser phục hồi Monica

3
Tôi cảm thấy như tôi chủ yếu nó.
Ross Presser

1
@GeroldBroser Điều đó sạch hơn, nhưng không thực sự cần thiết: khoảng trắng giữa các mã thông báo trong nhiều trường hợp là tùy chọn, chúng chỉ được yêu cầu khi việc ghép hai mã thông báo tiếp theo cũng có hiệu lực.
MC Hoàng đế

44

Làm sao main không thể được sử dụng như một định danh trong khi nó được sử dụng như định danh để khai báo phương thức "chính"?

Đối với một thành ngữ cổ điển như vậy:

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

main không phải là một từ khóa và nó có thể sẽ không bao giờ là một từ khóa trong Java vì lý do tương thích retro rõ ràng.


Về câu hỏi, là main một định danh tốt?

Đầu tiên: hợp lệ cho một trình biên dịch không có nghĩa là tốt.
Ví dụ, java1234tùy chọn được đề xuất cũng là một định danh hợp lệ nhưng điều đó thực sự nên tránh.

maincó một ý nghĩa rất đặc biệt và quan trọng: nó được sử dụng làm phương thức điểm vào của các lớp và các tệp được thực thi bởi javadòng lệnh.
Việc sử dụng maincho một tên phương thức không điền vào các tiêu chí được sử dụng bởi javadòng lệnh sẽ chỉ gây hiểu nhầm trong khi sử dụng nó làm tên biến hoặc tên lớp có thể có ý nghĩa.
Ví dụ: xác định lớp đại diện cho điểm vào của một ứng dụng vì Mainlớp của ứng dụng có thể được chấp nhận và do đó sử dụng nó làm tên biến cũng như:

public class Main {

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

}

Nói chung, trong Java, nhiều ký tự hoặc "từ" được coi là định danh hợp lệ cho trình biên dịch nhưng không được khuyến khích sử dụng trong mã máy khách (nhưng mã được tạo có thể làm điều đó: ví dụ các lớp lồng nhau) là không thể đọc được và / hoặc thực sự sai lệch.

Ví dụ, điều này có thể hợp lệ cho trình biên dịch:

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$);
    }    
}

Nhưng chúng tôi không muốn:

  • để đặt tên Objectlớp của chúng tôi vì điều này được định nghĩa trongjava.lang (1).
  • đặt tên cho một phương thức main()nếu không điền các tiêu chí được sử dụng bởijava dòng lệnh (2).
  • làm quá tải Object.toString() phương thức (3).
  • để đặt tên cho các biến của chúng tôi với _, $hoặc bất kỳ ký tự đáng ngạc nhiên / không thể thay đổi nào đi ngược lại các quy ước đặt tên được chia sẻ (4).

7
Chỉ cần lưu ý, maincó thể là một từ khóa chỉ có thể sử dụng làm tên cho một phương thức tĩnh với một chữ ký thích hợp (hoặc bất cứ điều gì). Lưu ý rằng các cuộc gọi siêu hạng sử dụng supertheo cách làm cho nó trông giống như một mã định danh: super(foo);super.foo, nhưng superlà một từ khóa (và trước khi thêm thuốc generic, đây là cách duy nhất để sử dụng nó (mà tôi có thể nhớ)).
jaxad0127

@ jaxad0127 Điểm thú vị nhưng tôi không hoàn toàn đồng ý. Trên thực tế, nó không phải và trong tương lai có lẽ không thể vì lý do tương thích. Nếu bạn đã xác định mainlàm từ khóa trong phiên bản mới của java, điều đó có nghĩa là bất kỳ mã nào sử dụng chính làm tên phương thức (hoặc bất kỳ tên thành viên nào) sẽ không biên dịch nữa. Việc sử dụng supertrong thuốc generic không có bất kỳ tác dụng phụ nào trong mã hiện tại vì thuốc generic không tồn tại vào thời điểm này.
davidxxx

2
Tôi chỉ có nghĩa là nó CÓ THỂ được thực hiện như một từ khóa. Chỉ vì nó trông giống như một định danh, không có nghĩa là nó phải như vậy.
jaxad0127

2
Tôi sẽ tranh luận rằng mainvẫn là một định danh tốt hơn java1234. Sử dụng nó cho một phương thức "thông thường" sẽ gây hiểu lầm, nhưng tôi không gặp vấn đề gì khi đặt tên một biến main, nếu đó thực sự là một cái gì đó chính trong phương thức của tôi. java1234thật kinh khủng, những cái tên nên được mô tả ...
AJPerez

1
"Về câu hỏi, chính là một định danh tốt?" Nó phụ thuộc. Tôi có lẽ sẽ không để mắt đến một biến có tên mainnếu chức năng mà tôi đang xem đã làm gì đó với dữ liệu chính của nước. Tôi sẽ ném lên nếu tôi từng thấy java1234trong mã sản xuất (và cầu nguyện không có 1233 biến khác có tiền tố java).
jpmc26

40

Nó có phải là một định danh hợp lệ? Đúng.

Nó có phải là một định danh tốt? Không phải nếu bạn đang sử dụng nó cho bất cứ điều gì khác ngoài phương thức bắt đầu khi khởi chạy JVM.

Là một định danh hợp lệ được liệt kê? Đúng.

Có phải các hướng dẫn kiểm tra nói để chọn câu trả lời tốt nhất?


7
Đồng ý - nhiều lựa chọn như thế này là về việc chọn câu trả lời đúng 'tốt nhất' khi có nhiều câu hỏi. Tuy nhiên, điều đó không làm cho câu hỏi này trở thành một câu hỏi trắc nghiệm hay và tôi nghĩ nói chuyện với giáo viên về nó là điều nên làm.
Bóng tối

19
@Shadow Đây là một khóa học lập trình. Sự mơ hồ về một câu hỏi về một cái gì đó được chỉ định với ngữ pháp toán học chính thức là không thể chấp nhận được. Nói đúng theo tiêu chuẩn đó (nghĩa là " hợp lệ "), cả hai câu trả lời đều đúng như nhau. Tôi có thể tưởng tượng nhiều trường hợp trong đó mainlà một định danh có thể chấp nhận được hơn tôi có java1234thể. Ví dụ, xem xét một cơ sở mã làm việc với dữ liệu cấp nước (nguồn nước).
jpmc26

5
Mặt khác, java1234 bốc lên trời cao như một định danh.
Joshua

4
"chọn câu trả lời đúng nhất" không có nghĩa là "tìm ra khi giáo viên không biết họ đang nói gì và đoán câu trả lời tồi mà họ đang nghĩ đến." chính không chỉ là một định danh hợp lệ , nó là một định danh rất quan trọng bởi vì mọi ứng dụng Java đều có một phương thức chính và các phương thức được đặt tên bằng các định danh.
fluffysheap

2
Tôi thấy câu trả lời này rất được quan tâm và tôi ước tôi có thể bỏ phiếu nhiều hơn một lần. Có vẻ như bạn đang cố gắng đứng về phía mình bằng mọi giá và không xem xét bức tranh rộng lớn hơn. mainlà một định danh hoàn toàn tốt ở bất cứ đâu ngoài miền hẹp của ứng dụng Java đơn giản. Nó có thể là tên của một trường trong một lớp đại diện cho một menu thiết lập. Hoặc một <main>phần của tài liệu trong trình tạo HTML. java1234, mặt khác, là khủng khiếp như nhận dạng nhận được.
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);
    }
}

7

Giáo viên đó đã mắc một lỗi nhỏ khi cho rằng chính không phải là định danh hợp lệ hoặc chỉ đơn giản là đặt sai câu hỏi. Anh ta có thể muốn nói "một định danh tốt".
Nhưng bỏ qua các đối số của con trai bạn và do đó không khuyến khích cách tiếp cận khoa học của ông là kiểm tra tài liệu liên quan (đặc tả Java) và thực hiện một thí nghiệm (viết chương trình mẫu) là điều hoàn toàn ngược lại với những gì giáo viên phải làm.


1
Như đã lưu ý trên các câu trả lời khác, mainthường là một định danh "tốt" hơn nhiều so với java1234. Vì vậy, ngay cả ở đó, giáo viên là sai. ;)
jpmc26

5

Cả hai mainjava123đều là các định danh hợp lệ , chính không phải là một từ khóa dành riêng nên nó hoàn toàn có thể chấp nhận để sử dụng, theo như thử nghiệm, bạn nên đạt được ít nhất một điểm hoặc nửa điểm.


5
  1. Nên là từ đơn. Đó là không gian không được phép.

    Ví dụ: xoài có giá trị nhưng giá xoài không hợp lệ.

  2. Nên bắt đầu bằng một chữ cái (bảng chữ cái) hoặc dấu gạch dưới hoặc ký hiệu $.

    Ví dụ: price, _price và $ price là các định danh hợp lệ.

  3. Không nên là một từ khóa của Java vì từ khóa mang ý nghĩa đặc biệt đối với trình biên dịch.

    Ví dụ: lớp hoặc void, v.v.

  4. Không nên bắt đầu bằng một chữ số nhưng chữ số có thể ở giữa hoặc ở cuối.

    Ví dụ: 5mangoescost không hợp lệ và mango5cost và mangocost5 là hợp lệ.

  5. Độ dài của một mã định danh trong Java có thể là 65.535 ký tự và tất cả đều có ý nghĩa. Định danh là trường hợp nhạy cảm. Đó là cả xoài và Xoài đều được đối xử khác nhau. Có thể chứa tất cả các chữ cái viết hoa hoặc chữ thường hoặc hỗn hợp.

IDENTIFIER : chúng là tên lớp, tên phương thức, tên biến ...

Vì chính không phải là một từ dành riêng và theo cách giải thích ở trên để xác định một định danh chính là một định danh hợp lệjava1234 cũng vậy. Các tùy chọn không có giá trị vì giải thích ở trên.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.