3

OCA Java SE 7 Programmer I Certification Guideという本を読んで、Java SE 7 Programmer I 試験 ( 1Z0-803 ) の準備をしています。この本には、著者が Java プログラミングで 12 年の経験を持ち、技術的な校正者 (おそらく給料で) がいるにも関わらず、多数の欠陥があります。

しかし、それが私を不安にさせることが1つあります。著者は 168 ページで、この声明は真実であると述べています。

メソッドの戻り値の型が の場合、メソッドはint型の値を返すことができますbyte

ええと、私は別の主張をしており、あなたの助けが必要です。例として、次のコードを取り上げます。

public static void main(String[] args)
{
    // This line won't compile ("possible loss of precision"):
    byte line1 = returnByte();

    // compiles:
    int line2 = returnByte();

    // compiles too, we "accept" the risk of precision loss:
    byte line3 = (byte) returnByte();
}

public static int returnByte()
{
    byte b = 1;
    return b;
}

明らかに、コンパイラは、returnByte()メソッド シグネチャの異なる戻り値の型 int と、メソッドの実装の最後に実際に返されるもの (バイト) について文句を言いません。バイトは int (32) よりも少ないビット (8) を使用し、精度が失われるリスクなしに int にキャストされます。しかし、戻り値は常に整数です! それとも私が間違っていますか?試験で何と答えたでしょう?

本のこのステートメントは正しいと言われているため、実際の戻り値の型が何であるかは完全にはわかりません。メソッドの実装の最後にキャストが発生していますか、それとも代入の直前にメイン メソッドでキャストが発生していますか?

現実の世界では、暗黙のキャストと精度を失うリスクを理解している限り、この質問は問題になりません。しかし、これは試験で出題される可能性のある問題の 1 つに過ぎないので、この問題に対する技術的に正しい答えを知りたいです。

明確化!

byte回答の大部分は、 aを anintにキャストできるかどうか、その場合に何が起こるかを知りたいと考えているようです。まあ、それは問題ではありません。返された型が何であるかを尋ねています。言い換えれば、著者の引用文は正しいですか、それとも間違っていますか? int へのキャストは、returnByte() メソッドが実際に戻る前または後に発生しますか? これが実際の試験で、この問題を受け取ったとしたら、何と答えたでしょうか?

コード スニペットの line1 を参照してください。著者の言うことが正しければ、戻り値がバイトになるため、その行はコンパイルされます。しかし、それはコンパイルされません。型昇格の規則によれば、int を 1 バイトに圧縮しようとすると、精度が失われる危険性があります。私にとって、それは戻り値が整数であることの証明です。

4

3 に答える 3

1

はい、できます。

  • 式の値は、返される前にbyte昇格されます。int

  • 実際の戻り値の型は、メソッド シグネチャで宣言されているとおりです - int

IMO、その本の著者が書いたことは多かれ少なかれ正しいです。return彼は、 「バイトを返す」ときにステートメントで発生する byte から int への昇格についての説明を省略しました。

メソッドの実装の最後にキャストが発生していますか、それとも代入の直前にメイン メソッドでキャストが発生していますか?

メソッド内でキャスト (昇格) が発生しreturnByteます。

現実の世界では、暗黙のキャストと精度を失うリスクを理解している限り、この質問は問題になりません。

byteaを anに昇格させても精度が失われることはありませんint。型が異なる場合、精度が失われる可能性がありますが、(仮説として) 昇格が実行される場所で精度が失われることは同じです。


これを扱う JLS のセクションは JLS 14.17 であり、式はメソッドの宣言された戻り値の型に割り当て可能returnでなければならないと述べています。昇格がメソッドで行われることを明示的に述べているわけではありませんが、暗示されています。さらに、これを実装する唯一の実用的な方法です。

(仮に)呼び出し元のメソッドで変換が行われた場合 (例: main)、次のようになります。

  • コンパイラは、returnステートメントが何をしているかを知る必要があります。Java クラスは個別にコンパイルできるため、これは不可能です。
  • コンパイラは、どの実際のメソッドが呼び出されるかを知る必要があります。メソッドがオーバーライドされている場合、これは不可能です。
  • メソッドにreturn異なる型の式を持つ 2 つ (またはそれ以上) のステートメントが含まれている場合、コンパイラはどちらreturnが実行されるかを知る必要があります。不可能だよ。

これが実際の試験で、この問題を受け取ったとしたら、何と答えたでしょうか?

私は答えたでしょう...「場合による」...そして別の視点に進みました。

技術的に言えば、メソッドは を返しますintが、returnステートメントは型を に変換できる任意の式を取ることができますint

しかし、メソッドが を返すと誰かが私に言った場合byte、私は彼らの意味を理解するでしょう.


また、私が知る限り、メソッド/関数はstorage.etcにスタックを使用し、それらのスタック内には、戻り先の(タイプ)ではなく、戻りアドレスを格納します。したがって、再び曖昧さが生じます(少なくとも私にとっては)。間違っている場合は修正してください。

はい、技術的にはメソッドは型を返しません。(たとえそれがTypeオブジェクトを返すとしてもです。それは型そのものではなく、型を示すオブジェクトです。) しかし、誰もが喜んで「returnByte メソッドは int 型を返す」と言うでしょう。

したがって、あなたが衒学者になるつもりなら、はい、それはあいまいです。しかし、解決策は衒学的にならないようにすることです。

于 2013-08-17T10:48:54.377 に答える
0

最後の8ビットを取得するのと同じであると確信しているmyInt << 24ため、整数が255(2 ^ 8)の値を超えると、精度が差し迫って失われます。

于 2013-08-17T10:38:12.510 に答える
0

はい、ステートメントは有効です。byte常にint快適にフィットします。

byte => int //no precision loss
int  => byte //precision loss

しかし、あなたがしている場合:

byte => int => byte //you won't lose any data

これがあなたがしていることです。それは役に立ちますか?

于 2013-08-17T10:52:17.473 に答える