main이 유효한 Java 식별자입니까?


288

내 아이들 중 하나가 고등학교에서 Java를 사용하고 있으며 그의 테스트 중 하나에서 이것을 가지고 있습니다.

다음 중 Java에서 유효한 식별자는 무엇입니까?

ㅏ. 123java
비. main
씨. java1234
디. {abce
이자형. )whoot

그는 b 에 대답 하고 잘못했습니다.

나는 질문을 보았고, 그 주장 main 이다 유효한 식별자과 잘 했어야있다.

식별자 에 대한 Java 사양 을 살펴본 후 그 점을 강화했습니다. 우리는 또한 main메소드 라는 변수를 가진 샘플 프로그램을 작성했습니다 . 그는 Java 문서 참조, 테스트 프로그램 및 교사가이를 무시하고 답변이 여전히 옳지 않다는 서면 반박을 작성했습니다.

main유효한 식별자는?


12
선생님이 너무 불안해서 새로운 것을 배우고 실수를 인정하는 것을 두려워하는 것은 항상 슬프게합니다.
Ryan Lundy

나는 그것을 추측한다. 그러나 실제로 변수 / 메서드 이름으로 사용해서는 안됩니다 (명백한 경우는 아니지만) 교사가 포인트를 드릴하려고하면 특히이 경우 메소드 이름에 대해 생각할 수 있습니다. 그녀의 요점.
bharal

3
아들의 선생님이 올바르게 일을하는지이 질문이 실제로 묻습니까? 두 개의 유효한 Java 식별자가 있습니다. 답은 'b' 'c'입니다. 그래서 선생님은 정확합니다. 아니면 뭔가 빠졌습니까?. 이것이 어떻게 SO 질문이 될 수 있습니까? 지역 사회의 일부가 아닌 사람에 대한 판단 ...
jschnasse

1
이것은 자바가 아닌 교사에 관한 질문입니다.
ACV

1
"자신의 트릭 질문에 속은"사례 중 또 다른 하나; 교사는 실제로 이와 같은 시험 문제를 작성하기 전에 언어 사양을 한 눈에 확인해야합니다.
jrh

답변:


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

이것은 컴파일되고 실행될 때이 출력을 내 보냅니다.

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

문자 순서 main는 키워드 또는 예약어가 아닌 식별자입니다.

JLS관련 섹션은 3.8입니다 .

식별자 의 무제한 길이의 순서입니다 자바 문자자바 자리 해야 처음있는, 자바 문자 .

식별자 :

    IdentifierChars이지만 키워드, BooleanLiteral 또는 NullLiteral은 제외

식별자

    JavaLetter {JavaLetterOrDigit}

JavaLetter :

    "자바 문자"인 유니 코드 문자

JavaLetterOrDigit :

    "자바 문자"인 유니 코드 문자

문자 순서 main는 위의 설명에 적합하며 3.9 절의 키워드 목록에 없습니다 .

(문자 시퀀스 java1234도 같은 이유로 식별자입니다.)


25
@Clockwork이 질문은 오직 하나의 선택 만이 맞을 수 있도록 표현되었습니다. 그러나 선택 bc 는 내재 된 선택과 일치하지 않는 질문의 조건을 만족시켰다. 이로 인해 OP의 아동은 교사가 옳다고 생각한 답 중에서 정답을 선택할 수있었습니다.
rgettman

@rgettman " b와 c "가 유효한 응답이 될 수있는 선택을 한 번 이상 허용 하는 " 다음 중 어느 것 ... "을 읽었습니다 .
TripeHound

6
@TripeHound "유효한 식별자"는 단수이며 정확히 1 개의 답변을 요구합니다. "유효한 식별자"와 비교
Gimme the 411

2
당신은 또한 수업 main을 만들 수있었습니다 ;)
Peter Lawrey

97

main 유효한 Java 식별자이며 교사가 잘못되었습니다.

관련 문서는 Java 언어 사양에 있습니다.

3 장. "Lexical Structure", 섹션 3.8. "식별자":

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

그것은 말한다 :

식별자는 길이가 무제한 인 Java 문자 및 Java 숫자 시퀀스이며 첫 번째는 Java 문자 여야합니다. 식별자는 키워드 (§3.9), 부울 리터럴 ( §3.10.3) 또는 null 리터럴 (§3.10.7) 또는 컴파일 타임 오류가 발생합니다.

이는 다음 중 하나에 의해 유효한 식별자임을 증명할 수 있음을 의미합니다.

  • 자바 키워드 (힌트 : 당신은 그것을 찾을 수 없습니다!) 또는 단순히
  • 이를 식별자로 사용하고 컴파일 타임 오류가 발생하지 않는 것을 관찰합니다.

1
좀 더 명시 적으로 인용하고 철자 할 수 있습니까?
zero298

36
전체 섹션이므로 아니요. 교사가이 섹션이 '메인'에 대해 어떤 종류의 예외를 만든다고 생각하면, 교사가 말하는 부분을 보여 주어야합니다.
Mike Nakis

76

다른 답변 상태로

main유효한 Java 식별자java1234입니다.

혼동은 그 main(String[])방법이 종종 JVM 1에 의해 진입 점으로 사용 된다는 사실에서 비롯된 것 같습니다 . 그러나 이것이 토큰 main자체가 식별자 2 로 사용될 수 없다는 것을 의미하지는 않습니다 .

스펙에 따르면 다음 선언도 유효합니다.

  • 필드 :

    private int main;
  • 지역 변수 :

    String main = "";
  • 방법:

    private void main() { ... }
  • 클래스 (소문자로 시작하는 클래스 이름은 권장되지 않지만) :

    public class main { ... }
  • 소포:

    package main;

1 : 주석에서 언급했듯이 JVM 사양 자체는 특정 방법을 진입 점으로 요구하지 않지만 널리 사용되는 java도구는 종종 진입 점과 같은 방법을 사용합니다.
2 : 나는 일반적으로 이외의 주요 방법을 만드는 것을 피할 것 main(String[])입니다.


22
"혼란이 main (String []) 메소드가 JVM의 진입 점으로 사용된다는 사실 때문에 혼란스러워합니다." mainJVM의 진입 점이 아닙니다. java도구가 응용 프로그램을 실행하는 데 사용 하는 진입 점입니다 . 다른 도구 (예 : 서블릿 컨테이너)는 다른 진입 점을 사용합니다.
TJ Crowder

27
"entry-point-context"메인에서도 이미 유효한 식별자이기 때문에 더욱 아이러니하다. 따라서 귀하가 이에 반대 할 수있는 경우에도 실제로
영업권이

@ TJCrowder 감사합니다. 답변에 포함 시켰습니다.
MC 황제

1
@Hobbamok 당신은 기본 자바 개념에 대해 혼란스러워하는 것 같습니다. 아마 당신이 왜 학교에서 그것을 가르치고 연습하지 않는지 는 마음에 오는 대답입니다.
rath

4
java도구는 필요하지 않습니다 main(String[])메인 클래스를 확장하는 경우 방법을 javafx.application.Application을 .
VGR

65

이것은 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);
    }
}

... 실행되면 출력이 생성됩니다.

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
static main다른 매개 변수로 다른 방법 을 추가 할 수 있습니까?
jpmc26

6
@ jpmc26 사용 해보고 어떻게 진행되었는지 알려주세요. :)
MichaelK

1
글쎄 그건 전원의 많은
MC 황제

4
@MCEmperor 예, 이것이 저의 대답에 대한 주요 주장입니다. ;)
MichaelK

3
추가하는 것을 잊었습니다 package main;!
Solomon Ucko

45

나는 그것에 할 수있는 모든 것을 던졌고 작동하는 것 같습니다. main이 유효한 식별자라고 말하고 싶습니다.

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
나는 그것을 좋아한다. 'grep -o main main.java | wc -l '
개리 박

3
이 코드는 프로그래밍 언어 "OK"를 떠올리게합니다. ^^이 코드의 거의 모든 단어는 "메인"입니다.
Florian Bach

public static void main(main...Main)( 공간 이 없음) 작동하지 않습니다.
GeroldBroser는 Monica를

3
나는 그것이 주된 것처럼 느낀다.
Ross Presser

1
@GeroldBroser 더 깨끗하지만 꼭 필요한 것은 아닙니다. 토큰 사이의 공백은 많은 경우에 선택 사항이며, 두 개의 후속 토큰의 연결이 유효한 경우에만 필요합니다.
MC 황제

44

main"메인"메소드를 선언하는 식별자로 사용되는 동안 식별자로 어떻게 사용할 수 없습니까?

그런 고전 관용구 :

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

main 는 키워드가 아니며 명백한 레트로 호환성을 이유로 Java에서는 키워드가 아닐 수 있습니다.


질문에 main대해 좋은 식별자입니까?

첫째 : 컴파일러에 유효하다고해서 반드시 좋은 것은 아닙니다.
예를 들어 java1234제안 된 옵션도 유효한 식별자이지만 실제로 피해야합니다.

main매우 특별하고 중요한 의미를 지니고 있습니다. java명령 행에서 실행되는 클래스 및 jar의 시작점 메소드로 사용됩니다 .
사용 main에 의해 사용되는 기준을 채우지 않는 방법 이름을 java명령 행은 변수 이름으로 사용하거나 클래스 이름은 의미를 만들 수있는 동안 단지 오해의 소지가 될 것이다.
예를 들어 응용 프로그램의 진입 점을 나타내는 클래스를 응용 프로그램의 클래스로 정의하는 Main것은 허용 가능하므로 다음과 같이 변수 이름으로도 사용하십시오.

public class Main {

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

}

일반적으로 Java에서 여러 문자 또는 "단어"는 컴파일러의 유효한 식별자로 간주되지만 클라이언트 코드에서 사용하지 않는 것이 좋습니다 (그러나 생성 된 코드는 다음과 같이 할 수 있음). 또는 오해의 소지가 있습니다.

예를 들어 이것은 컴파일러에 유효 할 수 있습니다.

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

그러나 우리는 원하지 않습니다 :

  • 이름을 Objectjava.lang(1)에 정의 된대로 클래스 합니다 .
  • 방법의 이름을 지정 main()java명령 행에서 사용할 기준을 채우지 않은 경우 (2).
  • Object.toString()방법 (3) 을 과부하 .
  • 우리와 변수 이름을 지정합니다 _, $또는 공유 이름 지정 규칙 (4)에 가서 어떤 놀라운 일 / unmeaningful 문자.

7
참고로, main적절한 서명 (또는 무엇이든)이있는 정적 메소드의 이름으로 만 사용할 수있는 키워드 일 수 있습니다. 수퍼 클래스 호출 super은 식별자처럼 보이게하는 방식으로 사용합니다 : super(foo);그리고 키워드 super.foo이지만 super키워드는 제네릭이 추가되기 전에이를 사용하는 유일한 방법이었습니다 (기억할 수 있음).
jaxad0127

@ jaxad0127 재미있는 점이지만 완전히 동의하지는 않습니다. 실제로는 그렇지 않으며 앞으로도 여전히 호환성 문제 일 수는 없습니다. mainjava의 새 버전에서 키워드로 정의한 경우 main을 메소드 이름 (또는 멤버 이름)으로 사용하는 코드는 더 이상 컴파일되지 않습니다. 현재 super제네릭이 없었기 때문에 제네릭에서 의 사용법은 기존 코드에서 부작용이 없습니다.
davidxxx

2
방금 키워드로 수행되었음을 의미했습니다. 식별자처럼 보인다고해서 꼭 그래야하는 것은 아닙니다.
jaxad0127

2
나는 main아직도 그것보다 더 나은 식별자 라고 주장 할 것이다 java1234. "일반적인"메서드에 그것을 사용하는 것은 오해의 소지가 있지만 변수 main가 실제로 내 메소드의 주요 무언가라면 변수의 이름을 지정하는 데 아무런 문제가 없습니다 . java1234그냥 끔찍한, 이름은 설명해야합니다 ...
AJPerez

1
"질문에 대해 주요 식별자는 좋은가?" 때에 따라 다르지. 내가 main보고있는 함수가 물의 주요 데이터로 무언가를했다면 아마도 명명 된 변수에 눈을 돌리지 않을 것입니다 . 프로덕션 코드에서 본 적이 있다면 포기합니다 java1234(접두사가있는 1233 개의 다른 변수가 없기를 바랍니다 java).
jpmc26

40

유효한 식별자입니까? 예.

좋은 식별자입니까? JVM을 시작할 때 시작하는 방법 이외의 용도로 사용하지 않는 경우.

유효한 다른 식별자가 있습니까? 예.

테스트 지침에 최상의 답변을 선택하라고 했습니까?


7
동의-다중 선택은 다중이있을 때 '최상의'정답을 선택하는 것입니다. 그러나 이것이 좋은 객관식 질문은 아니며 교사와 이야기하는 것이 옳은 일이라고 생각합니다.
Shadow

19
@Shadow 이것은 프로그래밍 과정입니다. 공식적인 수학 문법으로 지정된 것에 대한 질문에 대한 모호성은 용납 될 수 없습니다. 해당 표준 ( " 유효한 "으로 암시 된 )과 엄격하게 말하면 두 대답 모두 똑같이 정확합니다. 내가 할 수있는 것보다 더 main견딜 수있는 식별자 인 경우를 상상할 수 java1234있습니다. 예를 들어 급수 데이터 (수도)로 작업하는 코드베이스를 고려하십시오.
jpmc26

5
반면에, Java1234는 식별자로 높은 하늘에 악취가납니다.
Joshua

4
"최고의 답변을 선택한다"는 말은 "선생님이 무슨 말을하는지 알지 못하고 자신이 생각하고있는 나쁜 답변을 추측 할 때 그림을 그려라"는 의미가 아닙니다. main은 유효한 식별자 일뿐만 아니라 모든 Java 응용 프로그램에는 기본 메소드가 있으며 메소드는 식별자로 이름이 지정되므로 매우 중요한 식별자입니다.
fluffysheap

2
이 답변에 대한 의견이 많았으며 한 번 이상이 투표에 참여할 수 있기를 바랍니다. 모든 비용을 부담하고 더 넓은 그림을 고려하지 않는 것 같습니다. main일반 Java 응용 프로그램의 좁은 도메인 외부의 완벽한 미세 식별자입니다. 세트 메뉴를 나타내는 클래스의 필드 이름 일 수 있습니다. 또는 <main>HTML 빌더의 문서 섹션. java1234반면에 식별자는 얻을 수있는만큼 끔찍합니다.
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

그 교사는 main 이 유효한 식별자가 아니라고 가정 하거나 단순히 질문을 잘못 표현 한다고 가정 할 때 사소한 실수를 저질렀습니다 . 그는 아마도 "좋은 식별자"라고 말하려고했다.
그러나 아들의 주장을 무시하고 관련 문헌 (Java 사양)을 확인하고 실험 (샘플 프로그램 작성)을 수행하는 그의 과학적 접근 방식을 방해 하는 것은 교사가해야하는 것과 정반대 입니다.


1
다른 답변에서 언급했듯이 main훨씬 더 자주 "좋은"식별자 java1234입니다. 그래서 선생님도 틀 렸습니다. ;)
jpmc26

5

모두 main하고 java123있는 유효한 테스트 당신이 적어도 포인트 또는 반 점을 얻었어야했는데가는대로까지 사용이 완벽하게 허용 그래서 식별자, 주 예약 된 키워드가 없습니다.


5
  1. 한 단어 여야합니다. 공백은 허용되지 않습니다.

    예 : mangoprice는 유효하지만 mango 가격은 유효하지 않습니다.

  2. 문자 (알파벳) 또는 밑줄 또는 $ 기호로 시작해야합니다.

    예 : price, _price 및 $ price는 유효한 식별자입니다.

  3. 키워드는 컴파일러에 특별한 의미를 부여하므로 Java의 키워드가 아니어야합니다.

    예 : class 또는 void 등

  4. 숫자로 시작하지 말아야하지만 숫자는 중간 또는 끝에있을 수 있습니다.

    예 : 5mangoescost가 유효하지 않으며 mango5cost 및 mangocost5가 유효합니다.

  5. Java에서 식별자의 길이는 65,535 자이며 모두 중요합니다. 식별자는 대소 문자를 구분합니다. 그것은 망고와 망고가 다르게 취급됩니다. 모든 대문자 또는 소문자 또는 혼합물을 포함 할 수 있습니다.

식별자 : 클래스 이름, 메소드 이름, 변수 이름입니다 ...

main은 예약어가 아니며 식별자를 정의하는 위의 설명에 따라 main은 유효한 식별자 이며 java1234 도 있습니다. 위의 설명으로 인해 나머지 옵션은 유효하지 않습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.