Java識別子の「接続文字」とは何ですか?


208

SCJPについて読んでいますが、この行について質問があります。

識別子は、文字、通貨文字($)、またはアンダースコア(_)などの接続文字で始まる必要があります。識別子を数字で始めることはできません!

有効な識別子名はアンダースコアなどの接続文字で開始できることを示してます。アンダースコアが唯一の有効なオプションだと思いましたか?他にどのような接続文字がありますか?


2
「通貨文字」について:この質問への英国の訪問者は驚かれ、「a」通貨文字で始めることができるのと同様に、Java識別子は合法的にはポンド記号(£)で始めることができることを知りたいと思うかもしれません。
8bitjunkie 2014年

11
Java 8以降_は「非推奨」の識別子です。具体的には、コンパイラーは次の警告を発行します(識別子としての '_'の使用は、Java SE 8以降のリリースではサポートされない場合があります)
aioobe 2014年

4
@aioobeうん。Brian Goetz氏は_、将来の言語機能で使用するために「再利用」していると述べています。アンダースコアで始まる識別子も問題ありませんが、ラムダパラメータ名として使用した場合、単一のアンダースコアはエラーとなり、それ以外の場所では警告となります。
Boann、2014年

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、2012

58
@MarkoTopolnikあなたが望むものに注意してください。;)
ピーター・ローリー

3
ところで、どの通貨記号も使用できます。int ৲, ¤, ₪₪₪₪;:D
Peter Lawrey

17
キックのためだけに、これらのコードの1つまたは2つをコードにスローする可能性があります。そして、ビルドシステムが本当に UTF-8に準拠しているかどうかをテストします。
Marko Topolnik、2012

82
@GrahamBorlandどうですかif( ⁀ ‿ ⁀ == ⁀ ⁔ ⁀) or if ($ == $)またはif (¢ + ¢== ₡)orif (B + ︳!= ฿)
Peter Lawrey

25

65k文字全体を反復処理し、尋ねますCharacter.isJavaIdentifierStart(c)。答えは: "アンダータイ" 10進数8255


14
私は(Scalaで)抵抗できませんでした:(1 to 65535).map(_.toChar).filter(Character.isJavaIdentifierStart).size-48529文字を生成します...
Tomasz Nurkiewicz

65k、12k、8.5kなどの近くにいくつかの文字があるようです
Markus Mikkolainen

「!isLetter」および「!isDigit」と言っても降伏しない
Markus Mikkolainen

2546 + 2547少なくとも「ボックス描画...」
Markus Mikkolainen

3
合計数= 90648、私はするつもりだCharacter.MAX_CODE_POINT、おそらく以上あります、2<<16
Martijn Courteaux 2012

7

正当なJava識別子の明確な仕様は、Java言語仕様に記載されています


3
どの文字がJava識別子を開始するかという(暗黙の)質問に実際に完全に回答するかどうかはわかりません。我々が終わるのリンクに続きCharacter.isJavaIdentifierStart()を述べた文字は、場合Java識別子を開始し、次のいずれかの条件がtrueの場合にのみ可能性があります... chが(通貨記号であるような「$」); chが(連結句読点文字であるような「_」)。
CVn

1
仕様では、受け入れ可能な文字の最終的なリストは実装に任されているようです。そのため、すべての人が異なる可能性があります。
グレッグヒューギル2012

3
@GregHewgill他のすべてがどれほど厳密に指定されているかを考えると、それはばかげたことでしょう。これらは実際にUnicode文字クラスであり、Unicode標準で定義されている(どこにあるか?)と思います。isJavaIdentifierStart()はgetType()に言及し、通貨記号とコネクタの句読点もどちらもその関数によって返されるタイプであるため、リストがそこに示されている場合があります。「一般カテゴリ」は、実際にはUnicode標準の特定の用語です。だから有効な値は以下のようになりL、[すべて] NlScPc
Random832 2012

3
@GregHewgillは正しいです。仕様は短くて明確で、Character.isJavaIdentifierStart()とCharacter.isJavaIdentifierPart()によって定義されています。終わり。覚えておくべき重要なことは、Unicodeは進化しているということです。文字セットが完成したと考える罠に陥らないでください(ラテン語はひどい例です。無視してください)。キャラクターは常に作成されます。日本の友達に聞いてください。正当なJava識別子が時間の経過とともに変化することを期待してください。重要なのは、人々が人間の言語でコードを記述できるようにすることです。これは、変更を許可するという厳しい要件につながります。
James Moore

6

Unicodeのコネクタ文字のリスト次に示します。キーボードでは見つかりません。

U + 005F LOW LINE _
U + 203F UNDERTIE‿U
+ 2040 CHARACTER TIE⁀U
+ 2054 INVERTED UNDERTIE⁔U + FE33垂直ローラインのプレゼンテーション フォーム

U + FE34
垂直波状ローラインのプレゼンテーションフォーム︴U + FE4Dダッシュ﹍U
+ FE4E CENTRELINE LOW LINE﹎U
+ FE4F WAVY LOW LINE﹏U
+ FF3F FULLWIDTH LOW LINE _


5
使用しているキーボードレイアウトはわかりませんが、_(U + 005F)と入力するのは簡単です。:)
bdonlan

4

接続文字は、2つの文字を接続するために使用されます。

Javaでは、接続文字は、Character.getType(int codePoint) / Character.getType(char ch)Character.CONNECTOR_PUNCTUATIONと等しい値を返す文字です。

Javaでは、文字情報はUnicode標準に基づいていることに注意してください。これは、Connector_Punctuationのエイリアスである一般カテゴリPcを割り当てることによって接続文字を識別するものです。

次のコードスニペット、

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;

どうやら、上記の宣言は、次の2つの接続文字(下位互換性...おっと!!!)のjdk1.7.0_80&jdk1.8.0_51でコンパイルできません。

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

とにかく、詳細はさておき、この試験はBasic Latin文字セットのみに焦点を当てています。

また、Javaの法的識別子については、ここに仕様が記載されています。詳細については、CharacterクラスAPIを使用してください。


1

Java識別子で許可される最も楽しい文字の1つ(ただし最初は許可されません)は、「ゼロ幅非結合子」という名前のUnicode文字(&zwnj;、U + 200C、https://en.wikipedia.org)です。 / wiki / Zero-width_non-joiner)。

これを、XMLの別の部分への参照を保持する属性値内のXMLの一部で一度使用しました。ZWNJは「幅がゼロ」なので見えません(カーソルと一緒に歩いている場合を除いて、直前のキャラクターに表示されます)。また、ログファイルやコンソール出力にも表示されませんでした。しかし、それは常に存在していました。検索フィールドにコピーして貼り付けると、取得されたため、参照された位置が見つかりませんでした。文字列(の表示部分)を検索フィールドに入力すると、参照された位置が見つかりました。これを理解するのにしばらくかかりました。

Zero-Width-Non-Joinerを入力することは、ヨーロッパのキーボードレイアウトを使用する場合、実際には非常に簡単です(簡単すぎる)。残念ながら、ほとんどのキーボードでは互いに直接隣り合って配置されており、誤って一緒に叩いてしまう可能性があります。

Javaに戻る:よく考えました。次のようなコードを書くことができます。

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

2番目のiにzero-width-non-joinerが追加されていますが(stackoverflowのエディターで切り取られた上記のコードではできません)、それは機能しませんでした。IntelliJ(16.3.3)は文句を言わなかったが、JavaC(Java 8)は既に定義された識別子について文句を言った-JavaCは実際にZWNJ文字を識別子の一部として許可しているようだが、リフレクションを使用してそれが何をするかを確認するとき、ZWNJ文字は識別子から取り除かれます-likeのような文字はそうではありません。


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が含まれています。:-(
トッド・オブライアン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.