Java 식별자에서 "연결 문자"란 무엇입니까?


208

SCJP를 읽고 있는데이 줄과 관련하여 질문이 있습니다.

식별자는 문자, 통화 문자 ($) 또는 밑줄 (_)과 같은 연결 문자로 시작해야합니다. 식별자는 숫자로 시작할 수 없습니다!

유효한 식별자 이름은 밑줄 과 같은 연결 문자로 시작할 수 있습니다 . 밑줄 만 유효한 옵션이라고 생각 했습니까? 다른 연결 문자 가 있습니까?


2
"통화 문자"와 관련하여 :이 질문에 대한 영국 방문객은 "a"통화 문자로 시작할 수있는 것과 동일하게 Java 식별자가 법적으로 파운드 기호 (£)로 시작할 수 있다는 사실을 알고 놀랄 수 있습니다.
8bitjunkie

11
Java 8부터는 _"더 이상 사용되지 않는"식별자입니다. 특히, 컴파일러는 다음과 같은 경고를 발생시킵니다. ( '_'를 식별자로 사용하는 것은 Java SE 8 이후 릴리스에서 지원되지 않을 수 있습니다) .
aioobe

4
@aioobe 예프. Brian Goetz는 _향후 언어 기능에 사용하기 위해 "다시 교정" 하고 있다고 말합니다 . 밑줄로 시작 하는 식별자 는 여전히 괜찮지 만 람다 매개 변수 이름으로 사용될 경우 단일 밑줄은 오류이며 다른 곳에서는 경고입니다.
Boann

1
바이트 코드의 경우, 시퀀스에 포함되지 않은 것은 . ; [ / < > :다음과 같습니다. stackoverflow.com/questions/26791204/… docs.oracle.com/javase/specs/jvms/se7/html/… 그 밖의 모든 것은 Java 전용 제한 사항입니다.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

@Boann 재미있는 것은 그들이 람다에서 사용하는 것을 허용하지 않는다는 것이지만, 아마도 람다에서 사용될 "이 인수를 무시하는"식별자로 되돌아 올 것이다. 방금 다음과 같이 사용하려고했습니다 _, _ -> doSomething();.
user31389

답변:


268

연결 문자 목록은 다음과 같습니다. 이들은 단어를 연결하는 데 사용되는 문자입니다.

http://www.fileformat.info/info/unicode/category/Pc/list.htm

U+005F _ LOW LINE
U+203F  UNDERTIE
U+2040  CHARACTER TIE
U+2054  INVERTED UNDERTIE
U+FE33  PRESENTATION FORM FOR VERTICAL LOW LINE
U+FE34  PRESENTATION FORM FOR VERTICAL WAVY LOW LINE
U+FE4D  DASHED LOW LINE
U+FE4E  CENTRELINE LOW LINE
U+FE4F  WAVY LOW LINE
U+FF3F _ FULLWIDTH LOW LINE

이것은 Java 7에서 컴파일됩니다.

int _, ‿, ⁀, ⁔, ︳, ︴, ﹍, ﹎, ﹏, _;

예입니다. 이 경우 tp열 이름과 주어진 행의 값입니다.

Column<Double> tp = table.getColumn("tp", double.class);

double tp = row.getDouble(︴tp︴);

다음과 같은

for (int i = Character.MIN_CODE_POINT; i <= Character.MAX_CODE_POINT; i++)
    if (Character.isJavaIdentifierStart(i) && !Character.isAlphabetic(i))
        System.out.print((char) i + " ");
}

인쇄물

$ _ ¢ £ ¤ ¥ ؋ ৲ ৳ ৻ ૱ ௹ ฿ ៛ ‿ ⁀ ⁔ ₠ ₡ ₧ ₣ ₤ ₥ ₫ € ₭ ₮ ₯ ₰ ₰ ₷ ₳ ₵ ₶ ₷ ︳ ︴ ﹍ ﹎ ﹏ ﹏ ﹩ $ _ ¢ £ ¥ ₩


109
이 식별자를 사용하는 코드를 상속받을 날을 기대합니다!
Marko Topolnik

58
@MarkoTopolnik 원하는 것을 조심하십시오. ;)
Peter Lawrey

3
BTW 통화 기호도 사용할 수 있습니다. int ৲, ¤, ₪₪₪₪;: D
Peter Lawrey

17
이 중 하나 나 둘을 내 코드에 던져 넣을 수도 있습니다. 그리고 빌드 시스템이 실제로 UTF-8을 준수 하는지 테스트합니다 .
Marko Topolnik

82
@GrahamBorland 방법에 대한 if( ⁀ ‿ ⁀ == ⁀ ⁔ ⁀) 또는 if ($ == $)또는 if (¢ + ¢== ₡)또는if (B + ︳!= ฿)
피터 Lawrey

25

전체 65k 문자를 반복하고 물어보십시오 Character.isJavaIdentifierStart(c). 대답은 "undertie"10 진수 8255입니다.


14
나는 (스칼라에서) 저항 할 수 없었다 : (1 to 65535).map(_.toChar).filter(Character.isJavaIdentifierStart).size
-48529

65K와 12K 및 8.5k 등 근처에 몇 글자있을 것 같습니다
마르쿠스 Mikkolainen

"! isLetter"및 "! isDigit"라고 말하면 생성되지 않습니다
Markus Mikkolainen

2546 + 2547 atleast "box drawing ..."
Markus Mikkolainen

3
총 수 = 90648이지만로 갈 Character.MAX_CODE_POINT2<<16입니다.
Martijn Courteaux

7

올바른 Java 식별자의 명확한 사양은 Java 언어 사양 에서 찾을 수 있습니다 .


3
실제로 어떤 문자가 Java 식별자를 시작할 수 있는지에 대한 (암시적인) 질문에 완전히 대답하지는 않습니다. 우리가 끝날 링크를 따라 Character.isJavaIdentifierStart () 상태 와 다음과 같은 조건의 경우에만 하나에 해당하는 경우 Java 식별자를 시작할 수 있습니다 문자를 ... 채널은 (통화 기호입니다 같은 "$는"); ch는 연결 구두점 문자 ( 예 : "_")입니다.
CVn

1
사양은 구현에 따라 허용 가능한 문자의 최종 목록을 남기므로 모든 사람에게 다를 수 있습니다.
Greg Hewgill

3
@GregHewgill 다른 모든 것을 얼마나 엄격하게 지정했는지 고려하면 어리석은 일입니다. 나는 이것이 유니 코드 표준에 정의 된 실제 유니 코드 문자 클래스라고 생각합니다. isJavaIdentifierStart ()는 getType ()을 언급하고 통화 기호 및 커넥터 구두점은 해당 함수가 리턴 할 수있는 유형이기도하므로 목록이 제공 될 수 있습니다. "일반 카테고리"는 실제로 유니 코드 표준에서 특정 용어입니다. 유효한 값이 될 것이다 그래서 L[모든], Nl, Sc, Pc.
Random832

3
@GregHewgill이 정확합니다. 사양은 짧고 명확하며 Character.isJavaIdentifierStart () 및 Character.isJavaIdentifierPart ()에 의해 정의됩니다. 끝. 기억해야 할 핵심은 유니 코드가 진화하고 있다는 것입니다. 문자 세트가 완성되었다고 생각하는 함정에 빠지지 마십시오 (라틴은 끔찍한 예입니다. 무시하십시오). 캐릭터는 항상 만들어집니다. 일본인 친구에게 물어보십시오. 법적 자바 식별자는 시간이 지남에 따라 변경 될 것으로 예상되며 이는 의도적 인 것입니다. 요점은 사람들이 인간 언어로 코드를 작성하도록하는 것입니다. 이는 변경을 허용하기위한 어려운 요구 사항으로 이어집니다.
James Moore

6

다음은 유니 코드로 된 커넥터 문자 목록 입니다. 키보드에서 찾을 수 없습니다.

U + 005F LOW LINE _
U + 203F UNDERTIE ‿
U + 2040 CHARACTER TIE ⁀
U + 2054 INVERTED UNDERTIE ⁔
U + FE33 프리젠 테이션 양식 VERTICAL LOW LINE _ U
+ FE34 프리젠 테이션 양식 VERTICAL Wavy를 LOW LINE ︴
U + FE4D 점선 LOW LINE ﹍
U + FE4E 중심선 LOW LINE ﹎
U + FE4F Wavy를 LOW LINE ﹏
U + FF3F 전각 LOW LINE _


5
어떤 키보드 레이아웃을 사용하고 있는지 모르겠지만 확실히 _ (U + 005F)를 쉽게 입력 할 수 있습니다. :)
bdonlan

4

연결 문자는 두 문자를 연결하는 데 사용됩니다.

Java에서 연결 문자는 Character.getType (int codePoint) / Character.getType (char ch)Character.CONNECTOR_PUNCTUATION 과 동일한 값을 리턴하는 문자 입니다.

Java에서 문자 정보는 연결 문자를 일반 카테고리 Pc ( Connector_Punctuation 의 별명)에 지정하여 연결 문자를 식별하는 유니 코드 표준을 기반으로합니다 .

다음 코드 스 니펫

for (int i = Character.MIN_CODE_POINT; i <= Character.MAX_CODE_POINT; i++) {
    if (Character.getType(i) == Character.CONNECTOR_PUNCTUATION
            && Character.isJavaIdentifierStart(i)) {
        System.out.println("character: " + String.valueOf(Character.toChars(i))
                + ", codepoint: " + i + ", hexcode: " + Integer.toHexString(i));
    }
}

jdk1.6.0_45에서 식별자를 시작하는 데 사용할 수있는 연결 문자를 인쇄합니다.

character: _, codepoint: 95, hexcode: 5f
character: ‿, codepoint: 8255, hexcode: 203f
character: ⁀, codepoint: 8256, hexcode: 2040
character: ⁔, codepoint: 8276, hexcode: 2054
character: ・, codepoint: 12539, hexcode: 30fb
character: ︳, codepoint: 65075, hexcode: fe33
character: ︴, codepoint: 65076, hexcode: fe34
character: ﹍, codepoint: 65101, hexcode: fe4d
character: ﹎, codepoint: 65102, hexcode: fe4e
character: ﹏, codepoint: 65103, hexcode: fe4f
character: _, codepoint: 65343, hexcode: ff3f
character: ・, codepoint: 65381, hexcode: ff65

다음은 jdk1.6.0_45에서 컴파일됩니다.

int _, ‿, ⁀, ⁔, ・, ︳, ︴, ﹍, ﹎, ﹏, _,  = 0;

분명히, 위의 선언은 다음 두 개의 연결 문자 (역 호환성 ... oops !!!)에 대해 jdk1.7.0_80 및 jdk1.8.0_51에서 컴파일하지 못합니다.

character: ・, codepoint: 12539, hexcode: 30fb
character: ・, codepoint: 65381, hexcode: ff65

어쨌든 세부 사항은 제외 하고 시험은 기본 라틴 문자 세트에만 중점을 둡니다 .

또한 Java의 법적 식별자의 경우 사양이 여기 에 제공 됩니다 . 자세한 내용을 보려면 Character 클래스 API를 사용하십시오.


1

Java 식별자에서 허용되는 가장 재미 있고 재미있는 문자 중 하나는 시작하지는 않지만 "Zero Width Non Joiner"라는 유니 코드 문자입니다 (& zwnj ;, U + 200C, https://en.wikipedia.org / wiki / Zero-width_non-joiner ).

나는 XML의 다른 조각에 대한 참조를 보유하는 속성 값 내부의 XML 조각에서 한 번 이것을 보냈습니다. ZWNJ는 "제로 폭"이므로 볼 수 없습니다 (커서를 따라 걷는 경우를 제외하고는 문자 바로 앞에 표시됩니다). 로그 파일 및 / 또는 콘솔 출력에서도 볼 수 없었습니다. 그러나 그것은 항상 거기에있었습니다 : 검색 필드에 복사하여 붙여 넣기하면 참조 위치를 찾지 못했습니다. 그러나 (보이는 부분) 문자열을 검색 필드에 입력하면 참조 위치가 발견되었습니다. 이것을 알아내는 데 시간이 걸렸습니다.

유럽 ​​키보드 레이아웃을 사용하는 경우 최소한 독일어 변형 (예 : "Europatastatur 2.02")에서 유럽 키보드 레이아웃을 사용할 때 Zero-Width-Non-Joiner를 입력하는 것은 실제로 매우 쉽습니다 (너무 쉽습니다). 두 개의 키인 AltGr + "." 불행히도 대부분의 키보드에서 서로 바로 옆에 있으며 실수로 쉽게 맞출 수 있습니다.

Java로 돌아 가기 : 다음과 같은 코드를 작성할 수 있다고 생각했습니다.

void foo() {
    int i = 1;
    int i = 2;
}

두 번째로 너비가 0이 아닌 조이너가 추가되었지만 (위의 코드에서는 스택 오버 플로우 편집기에서 스니핑 할 수 없음) 작동하지 않았습니다. IntelliJ (16.3.3)는 불평하지 않았지만 JavaC (Java 8)는 이미 정의 된 식별자에 대해 불평했습니다 .JavaC는 실제로 ZWNJ 문자를 식별자의 일부로 허용하지만 리플렉션을 사용하여 ZWNJ를 수행 할 때 ZWNJ를 허용합니다 is와 같은 문자가 아닌 문자가 식별자에서 제거됩니다.


0

식별자 내에서 사용할 수있는 문자 목록은 시작 부분이 아니라 훨씬 더 재미 있습니다.

for (int i = Character.MIN_CODE_POINT; i <= Character.MAX_CODE_POINT; i++)
    if (Character.isJavaIdentifierPart(i) && !Character.isAlphabetic(i))
        System.out.print((char) i + " ");

목록은 다음과 같습니다.

I wanted to post the output, but it's forbidden by the SO spam filter. That's how fun it is!

대부분의 제어 문자가 포함되어 있습니다! 나는 종소리와 똥을 의미합니다! 소스 코드를 fn 종으로 울리게 할 수 있습니다! 또는 부드러운 하이픈처럼 가끔 만 표시되는 문자를 사용하십시오.


DEL 문자 인 \ u007f를 포함합니다. :-(
Todd O'Bryan
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.