• ベストアンサー

Java intの扱い

こんにちは、Javaを勉強しているものです。 小さなデータ(byteなど)をより大きないれもの(intなど)に入れるときには、暗黙的なキャストがおこなわれます。 逆に、大きな値を小さないれものに入れるための変換を「縮小変換」と呼び、これには明示的なキャストが必要だと習いました。 そこで、次のようなコードがあった場合、これは明示的なキャストが必要なのではないのでしょうか? byte b = 3; これは、コンパイルエラーにはならないのですが、 3はint型であり、bはbyte型なので、大きな値を小さな小さないれものに入れているということになります。本来であれば byte b = (byte)3; と書くべきではないのでしょうか? 宜しくお願い致します。

  • Java
  • 回答数4
  • ありがとう数4

質問者が選んだベストアンサー

  • ベストアンサー
  • neko_noko
  • ベストアンサー率45% (146/319)
回答No.4

No2です。こちらこそ遅くなりましてすみません。 遅くなりましたが、補足への回答をさせていただきます。 >int型以外でもリテラル値であれば、どのようなものでも自動的に型変換されるのでしょうか? 大きい型の変数に小さい型のリテラル値を代入する場合は 既にご指摘の通り、そのまま代入可能です。 double e = 3.5F; リテラル値はデフォルトは「整数ならint」、「小数ならdouble」のようです。 明示的にintやdouble以外を指定した場合、 //int i = 3F; のような指定はできないようです。 その他にもいろいろあるようですが、これ以上のことを言うとボロが出そうなので、 代わりに参考ページを挙げておきます。 言い訳させてもらうと、このような問題は、現場(実際のコーディングをする場合)は、 あまり問題にはならないはずです。 というより、「問題にしてはいけない」ことだと思います。 書いたコードがintか、shortかということより、本来達成すべきロジックがあるだろう、 という意味です。 byte b = 3;か、byte b = (byte)3;であるかは、 事前にコーディング規約として決定してあるものに従うべきなんでしょう。 話がそれてしまった… まあ、知っておいて損するものではないでしょうし、いずれ新人さんが 「なんでこれがエラーになるんですか?」と言われた時に、 サラッと答えられるように覚えておくのも良いですね。

参考URL:
http://www.okapiproject.com/java/java_ref/foundation/manual_02.htm
geocrew1
質問者

お礼

解りやすい説明ありがとうございます。 このようなことにこだわるのは、私がSJC-P試験の勉強をしているからなのです。いろいろと参考紹介などもあげて頂いて本当に助かりました。

その他の回答 (3)

  • liar_adan
  • ベストアンサー率48% (730/1515)
回答No.3

代入変換の例外として、特別に認められています。 「Java言語規定 5.2 代入変換」 http://www.y-adagio.com/public/standards/tr_javalang/5.doc.htm#170768 >次の条件をすべて満足すれば,プリミティブ型の縮小変換を使用してもよい。 > * 式が型byte,short,char又は,intの定数式。 > * 変数の型が,byte,short又はchar。 > * 式の値(定数式なのでコンパイル時にわかる)が,その変数の型で表現可能 初期化時に byte b = (byte)3; と書くのは面倒だし、上の条件を満たしている場合には 問題になることはあまり考えられないので、認めることにしたのでしょう。

geocrew1
質問者

お礼

お返事が遅くなり申し訳ございません。 詳しいご説明ありがとうございます。 >式が型byte,short,char又は,intの定数式。 これは=より右辺のこと > * 変数の型が,byte,short又はchar これは=より左辺のこと という理解で正しいでしょうか?

  • neko_noko
  • ベストアンサー率45% (146/319)
回答No.2

>逆に、大きな値を小さないれものに入れるための変換を「縮小変換」と呼び、これには >明示的なキャストが必要だと習いました。 これは正しいです。 ただし、byteやshortにリテラル値を代入する場合は、ちょっと特殊なようです。 byteやshortにリテラルの値を代入する場合、代入する変数の型に合わせて自動的に型変換されるようです。  byte b = 3;  //(1)リテラルなら自動的に型変換されるので代入可能  int i = 3;  //b = i;  //(2)リテラルでない場合はだめ。  //b = 128;  //(3)リテラルでもbyteの範囲を超えるものは自動変換できずエラーになる。 (1)と(2)は同じ値を代入してるように見えますが、 (1)リテラル値3がbyteに変換されるため代入可能です。 (2)は、リテラルでないため、自動変換されず代入できません。 ちなみに、リテラルであってもその型のデータ範囲を超える値は代入できません。 なので、(3)は代入不可です

参考URL:
http://www.nextindex.net/java/literal.html
geocrew1
質問者

お礼

お返事が遅くなり申し訳ございません。 解りやすい説明、ありがとうございます。 リテラル値の場合は、自動的に型変換されるというのは存じておりませんでした。int型以外でもリテラル値であれば、どのようなものでも自動的に型変換されるのでしょうか?

  • kgi03334
  • ベストアンサー率26% (24/90)
回答No.1

byte b = (byte)3; と書くべきです。

参考URL:
http://javafaq.jp/S007.html
geocrew1
質問者

お礼

お返事ありがとうございます。 書くべきというのは、分かりますが、 byte b = (byte)3; は、コンパイルエラーにはなりませんよね? 例えば、short型にdouble型を入れようとすると明示的なキャストがなければコンパイルエラーになります。 今回のケースだけコンパイルエラーにならない理由は何でしょうか?

関連するQ&A

  • C#で型変換がうまくいきません。

    C#で型変換がうまくいきません。 short r; byte[] b = new byte[] {1,2,3}; r = (short)b[1] * (short)256; というコードを書くと、 型 'int' を 'short' に暗黙的に変換できません。明示的な変換が存在します。(cast が不足していないかどうかを確認してください) と出てしまいます。キャストしているのに何がいけないのか全くわかりません。 どうぞ宜しくお願いいたします。

  • C# int→byte のキャスト

    プログラミング初心者です。 int型の変数に255以上の値を代入し、byte型の変数にcastするとbyte型の変数に代入される値はint変数の値から256を引いた値になります。なぜですか、またどういう仕組みでcastは行われるんですか?

  • 16進数のマスク処理

    C#勉強中です。 以下のようなコードを書いてコンパイルをかけたところ、「型 'uint' を 'int' に暗黙的に変換できません。明示的な変換が存在します。(cast が不足していないかどうかを確認してください) 」と出ました。この理由がわかりません。 0xFFFF00FFはなぜ符合なしとなってunsigned扱いになるのでしょうか。 [Code] int ret = 0; ret &= 0xFFFF00FF;

  • 暗黙のキャストを自動検出

    C++には暗黙のキャストがあります。 例えば、下記の例のようにint型(4バイト)の引数を取る関数short型(2バイト)の引数を与えて呼び出した場合。 ------------------- void func(int i) { //... } int main() { short s = 1; func(s); // short->intに暗黙のキャスト } このコードは正常にコンパイルすることができ、かついかなる警告レベルでも警告は表示されません。(VS環境) データ欠損やオーバーフローの可能性はなく、安全なキャストであることが保障されているからです。(short型の取り得る値の全てがint型の散り得る範囲に収まる) このような「暗黙のキャスト」を行っている箇所を自動的に検出する方法はあるでしょうか? 暗黙ではない(危険な)キャストはIDEにより警告が出ることは分かっています。 Visual Studiioの機能、または外部ツールを使用する方法でも構いません。あるいは、この目的のためにダミーを作成するようなやり方でも構いません。 funcを使用している箇所は膨大ですがfuncの数は限られていますので、この目的のために仮の関数を定義してコンパイルしてみることは可能です。 一応考えてみた方法は、下記のような検出用の関数を追加することです。 ------ 暗黙のキャスト検出用オーバーロード関数 ------- void func(short i) // 必要に応じてchar型や byte型をとるオーバーロード関数も作成 { // この関数が呼ばれたら暗黙のキャスト! cout << "関数" << __FUNCTION__ << "で暗黙のキャスト(int->short)が行われました。">>"\n"; // 続きの処理を継続するため、本当の関数を呼んでおく func((int)i); // ここは明示的にキャストしないと自分自身を呼んでしまう } ただこの方法ではコンパイル時に検出できず、実際に全ての関数呼び出しが実行されるようにプログラムを動かす必要があります。 また、検出用関数も暗黙のキャストのパターン数分用意する必要があります。目視で全ソースチェックするのとあまりコストが変わらないような気がします。 主に関数の引数として渡されるデータ型が仮引数にコピーされる際にキャストされる場面を検出したいのですが、関数の戻り値を別の変数に代入している場面も検出できればなお良いです。 なぜこのようなことが必要かと思われるかもしれませんが、暗黙のキャストそのものが問題ではなく、そうした箇所に別の問題が潜んでいる可能性があり、それを調べたいのです。 こうした場面がソース中に大量にあると想定されるため、漏れなく機械的に検出する方法があればと思い質問しました。

  • JAVA キャスト

    public class Test1{ public static void main(String[] args){ byte b1 =3; byte b2 =5; byte b3 =b1*b2; System.out.println("b3="+b3); } } キャストしてコンパイル出来る形にするにはどうしたらいいでしょうか?

    • ベストアンサー
    • Java
  • Javaについて

    明日学校でミニテストがあるのですが、例題で出された問題がどうしても解けません。 分かる方教えていただけたら助かります。 回答よろしくお願いします。 ・Javaはオブジェクト指向をとりいれた『   』言語 ・実行するためには『   』コマンドによって、中間ファイルを作り、『    』コマンドによって実行する。 ・オブジェクト指向において、クラスは『設計図』であり、クラスを基に実体であるインスタンスを生成する。 ・int型の変数「number」を定義し、値「13」を代入しなさい。 ・以下のコードではエラーとなるため、キャストが必要です。適切なキャストを追加し、実行できるコードに修正してください。  int number = 1.3;

  • int型の内容をbyteの配列にコピー

    int型の内容をbyteの配列にコピーする方法を教えて下さい。 int i_value = 500; byte[] by_value; by_value = new byte[4]; // どのような処理が必要ですか? by_value[0]には、0x1 by_value[1]には、0xf4 と格納したいです。 数字→文字列→文字(byte)できたのですが…。 C言語の場合、memcpy関数で型が異なってもキャストすれば回避できました。 JAVAでの方法を教えて下さい。

    • ベストアンサー
    • Java
  • Javaは全く扱ったことがないのですが、Javaのコードを読んでいて意

    Javaは全く扱ったことがないのですが、Javaのコードを読んでいて意味の理解できないところがあったので質問させてください。 次のような宣言を行った場合、配列Xの内容はどうなるのでしょうか? 4つめの0x78だけはbyte型への型変換が行われていないようなのですが・・・。 final byte[] X = { (byte)0x12, (byte)0x34, (byte)0x56, 0x78}; よろしくおねがいします。

    • ベストアンサー
    • Java
  • javaのbyte配列へintなどを埋め込む方法

    javaのbyte配列へintなどを埋め込む方法 java初心者です。データ編集がわからなくて悩んでいます。 下記のコードは"棒読みちゃん"といソフトへのTCPパケットを作成するコードです。 char buf[15]; *((short*)&buf[0]) = 0x0001; *((short*)&buf[2]) = speed; *((short*)&buf[4]) = tone; *((short*)&buf[6]) = volume; *((short*)&buf[8]) = voice; *((char* )&buf[10]) = 2; *((long* )&buf[11]) = len; 同じことをJAVAでしたいのですがわかりません。 (バイト型配列へint,long型を簡単に埋め込む方法がわかりません) よろしくお願いします。 よかったら、こちらもお願いします memcpy(&buf[15],message,strlen(messege)); TCPパケットのようなデータ処理が頻繁にある場合、 このようなコードは、どうしたらいいでしょうか? *((unsigned char* )&buf[15]) = message; CとJAVAになってますが、このような処理を簡単に書けないでしょうか?

    • ベストアンサー
    • Java
  • javaのパッケージについての質問です。

    すっきりわかるjava入門という本を参考にjavaを勉強しているのですが、 6.3パッケージを利用する という項目でサンプルコードに従って同じファイルの中に package calcapp.main; public class Calc{ public static void main(String[]args){ int a=10;int b=2; int total=calcapp.logics.CalcLogic.tasu(a,b); int delta=calcapp.logics.CalcLogic.hiku(a,b); System.out.println("足したら"+total+"引いたら"+delta); } } と package calcapp.logics; public class CalcLogic{ public static int tasu(int a,int b){ return(a+b); } public static int hiku(int a,int b){ return(a-b); } } という、二つの違うパッケージに入ったソースコードを作って、コンパイルしてみたのですが、 コマンドプロンプトに、javac CalcLogic.javaと打つ方は上手くいくのですが javac Calc.javaの方はパッケージcalcapp.logicsは存在しません、と言われ上手くいきません。 また、javac CalcLogic.java Calc.javaと打つとコンパイルは上手くいくのですが java Calcはexception in thread"main"java.lang.NoClassDefFoundErrorとでて上手くいきません。 長文の上足りない情報があったりするかもしれませんがわからなくて困っているのでどなたか教えていただけると 助かります。よろしくお願いします。

    • ベストアンサー
    • Java

専門家に質問してみよう