2009-10-29 7 views
13

なぜJavaでは(私は他のプログラミング言語も知らない)識別子が数字で始まっていない可能性があり、なぜ次の宣言も許されないのですか?なぜ識別子は数字で始まらないのですか?

int :b; 
int -d; 
int e#; 
int .f; 
int 7g; 
+0

一部の言語ではダッシュを使用できます。 –

答えて

39

一般的に、あなたは、2つの理由のために制限のようなものを置く:

  1. それは電子的に解析するための痛みです。
  2. 人間が解析するのは苦痛です。

は、次のコードスニペットを考えてみましょう:

int d, -d; 
d = 3; 
-d = 2; 
d = -d; 

-dが正当な識別子である場合には、その値dは終わりがありますか? -3または2?あいまいです。

も考慮してください。

int 2e10f, f; 
2e10f = 20; 
f = 2e10f; 

fは最後にどのような価値がありますか?これもあいまいです。

また、どちらの方法でも読んでも苦労します。誰かが2ex10を宣言した場合、それは2百万のタイプミスか変数名ですか?識別子は文字で始まることを確認して

は、彼らがと競合することができる唯一の言語項目は、キーワード予約されていることを意味します。

6

これは、Java言語仕様のsection 3.8がそう言っているからです。

識別子は、Java文字とJava 桁の無制限の長 配列で、その第一は、 のJava文字でなければなりません。識別子には、キーワード(§3.9)、ブール値 リテラル(§3.10.3)、またはヌルリテラル (§3.10.7)と同じスペル(ユニコード文字 シーケンス)の をキーワードとして持つことはできません。 については

この決定が行われた理由:これは構文解析を簡素化するためか、あいまいな文法を回避し、言語の将来のバージョンでおよび/または歴史的な理由のために特別な構文の導入を可能にする(つまり、他のほとんどの言語ので、同じ制限があります)。

int -d = 7; 
System.out.println("Some number: " + (8 + -d)); 

は、識別子の最初の部分、または単項マイナスマイナスです:-dであなたの例の例は、特に明確であることに注意してください?あなたが変数として-ddの両方を持っていた場合

さらに、それは完全にあいまいになる:

int -d = 7; 
int d = 2; 
System.out.println("Some number: " + (8 + -d)); 

は結果15または6か?

+0

@Carl Manaster:ニース。残念ながら私たちの編集は交錯しました。今すぐ修正しました。 – Stephan202

3

数字はリテラル値を表すために使用されているので、コンパイラが数値で始まるトークンを見つけたらリテラルを処理していることがわかります。識別子が数字で始まる場合、コンパイラは先読みを使用してトークン内の次の文字を見つけ、それが識別子かリテラルかを調べる必要があります。

+0

厳密に言えば、貧弱なコンパイラを意味するものではありません。彼らはとても大変です。 –

1

言語によってはこれらの事柄の一部が許可される可能性がありますが、この簡単な前提により、コンパイラライターとプログラマがプログラムを読みやすくなります。

パーサーは、ソーステキストを最初に「トークン」に分割するために(通常は)書き込まれます。数字で始まる識別子は数字のように見えます。 5e3に加えて、一部の言語では有効な番号(5000.0)です。

一方:と。演算子としてトークン化されます。状況によっては、これらのいずれかで始まる識別子があいまいなコードになることがあります。その他

0

各言語では、識別子の有効な文字とは何かを定義する必要があります。考慮の一部は解析の容易さになるだろう、部分はあいまいさを避けることになるだろう(言い換えれば、完璧な解析アルゴリズムでさえいつも確信することはできない)、部分は言語設計の好みになるだろう(JavaのC、C++との類似性)、いくつかはちょうど任意のものになるでしょう。

ポイントは何かでなければならないので、これはそのままです。

2

そのようなものは、ほとんどの混乱を防ぐために、(私は今1を考えることはできません)ちょうど約あらゆる言語で許可されていません。

例-dは、優れた例です。コンパイラは、「変数-d」または「変数dの数値の負数」を意味するかどうかをどのように知っていますか?あなたがファイルの残りの部分を読まずにそれを打ち込んだときに何が起こったのか分からないので、と言えないので、それは許されません。

例7gは同じものです。最後に文字を追加することで、特定の基数や型として数値を指定することができます。 8357はJavaのint型で、8357Lはlong型です(最後に 'L'があるため)。変数が数値で始まる場合、変数名かリテラルかを判断できない場合があります。

私はあなたが記載されている他の人を引き受けることになるのいくつかは、歴史的であってもよいし、その背後にある同じような理由を持っている(すなわち、それらはルールを守ってCは理由Xのためにそれを行うことができなかった、とJavaはCのように見えるように設計されています)。

実際にはほとんど問題にはなりません。そんなことが面倒な状況を見つけるのは非常にまれです。一番上に走るのは数字で始まる変数ですが、あなたはいつでもそれらを綴ることができます(つまりoneThing、twoThing、threeThingなど)。例えば

0

、我々はこれらの名前を持つオブジェクトを持つことを望む多数回はありませんか?

2ndInning 
3rdBase 
4thDim 
7thDay 

誰かが名前666で変数を持ってしよう可能性がある場合を想像:

int 666 = 777; 
float 666F = 777F; 
char 0xFF = 0xFF; 
int a = 666; // is it 666 the variable or the literal value? 
float b = 666F // is it 666F the variable or the literal value? 

おそらく、我々は考えるかもしれない一つの方法は、数字で始まる変数は、アルファベットで終わらなければならないということです - 限り として、それは0xで起動しないとhexadeciamal桁として使用し、文字で終わる、または それは、そのようなLまたはFなどの文字で終わらない、 などなど

しかし、そのようなルールはそれを作るだろう再Yogi Berra氏がおっしゃったようにプログラマーにとっては難しいのですが、同時にどのように考えることができますか?あなたはできるだけ早くエラーのないようにコンピュータプログラムを書こうとしています。そして、これらの小さな部分とルールのすべてを気にする必要があります。私はむしろ、プログラマーとして、変数の名前付けの簡単なルールを持っています。

データベースに挿入するためにデータログとデータストリームを解析するためにlexersとregexpを使用した私の努力の中で、数字で始まるキーワードや変数を見つけられなくなったので、解析が難しくなりました。あいまいさを取り除くために可能な限りパス。

したがって、コンパイラがプログラマにとって簡単になるほどで​​はありません。

関連する問題