Javaの不思議
- Javaでの型変換についての不思議な挙動について質問です。
- C言語と比べてJavaの型変換方法について不思議に思っています。
- JavaのIntegerクラスのdoubleValueメソッドについて疑問があります。
- ベストアンサー
javaの不思議
C言語をたしなむ程度にやっているものです。 Javaを勉強していたのですが、不思議だなと思ったので質問させてください。 Integer value = new Integer(30); value.doubleValue() // <- double型に変換している このプログラムだとvalueはintなのにあらかじめdoubleに変換できることを想定しています。 C言語の癖なのかしらないですが、型変換をするならクラスメソッドではなくキャストするか、 メソッドに投げる(Integer.toString←stringにする例ですが)。 この2つの方法が自然な型変換だと思うのですが、変でしょうか?
- Oforest
- お礼率8% (27/301)
- Java
- 回答数6
- ありがとう数1
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
前の回答にもあるようにInteger#doubleValueは キャストではありません が。 実際にJavaのJDKのライブラリでは キャストを行っているだけです。 なら尚更不思議と思ったかも知れませんが、 これがJDKユーザのユーザビリティを考慮したものだとしたら如何でしょうか? (それが邪魔くさいというのであればその機能を使わなければ良いだけの話ですし、 Javaを使わなければ良いだけの話です。) ですが結キャストにおけるビット0ビット追加も、 ダウンキャストにおけるビットの抜き出しも ほぼ同じアルゴリズムだと思います だからこそユーザが言語を選択すればよいと思います。
その他の回答 (5)
- 中村 拓男(@tknakamuri)
- ベストアンサー率35% (674/1896)
ひょっよして int と Integer をごっちゃにしているとか? Integer ならメソッド呼び出しが自然だと思います。 #クラスで普通キャストはしない。
- root139
- ベストアンサー率60% (488/809)
まず、念のために確認ですが、JavaでもCと同じ様な構文でキャストは出来ます。 例) ------------------------------------ int intVal1 = 30; double dblVal1 = intVal1; // 暗黙のキャスト double dblVal2 = (double) intVal1; // 明示的なキャスト int intVal2 = (int) dblVal1; // double → int は明示的なキャストのみ化 ---------------------------------------- > Integer value = new Integer(30); > value.doubleValue() // <- double型に変換している int を double に変換するだけならこのような書き方はあまりしないと思います。(キャストで十分なので) 元々Integer型のオブジェクトが有った場合には、このように doubleValue() で取出すのが自然でしょう。 また、オートボクシング/アンボクシングが導入されたJava5.0からは、Integer型を double にキャストするかのごとくに書くことも出来ます。 あまりお勧めはしませんが。 例) ------------------------------------ Integer objInt = Integer.valueOf(30); double dblVal = objInt; ---------------------------------------- 上記の処理はコンパイル時に↓のように書き換えられています。 double dblVal = (double) objInt.intValue();
- koko_u_u
- ベストアンサー率18% (216/1139)
> この2つの方法が自然な型変換だと思うのですが、変でしょうか? まず、doubleValue() は「型変換」ではありません。ただのメソッド呼び出しです。 上記のサンプルは例のための例なので、コード自体を検討する価値はありません。 toString() も「型変換」ではなくメソッド呼び出しです。 キャストの構文は別でありますが、推奨されません。そもそもキャストが不要になるようにコーディングしましょう。
- osamuy
- ベストアンサー率42% (1231/2878)
valueはIntegerクラスのインスタンスなので、値を求めるなら、オブジェクトにメッセージdoubleValue()を送信するのがオブジェクト指向プログラミング的に自然かと。 変だなと思う気持ちもわからないでもないですが。
- kmee
- ベストアンサー率55% (1857/3366)
Cは少し忘れることです。 Intergerとintは違います。 intはCのintと同じでただの整数です。メソッドはありません。 Integerはクラスです。メソッドやフィールドがあったりします。 Cでも struct Integer{int v;} value = {30}; double d = (double)value ; なんてことはしませんよね?(よっぽどの事情が無いかぎり) > value.doubleValue() // <- double型に変換している 変換はしていません。valueが持っている整数の値をdoubleとして返しているだけです。 > メソッドに投げる(Integer.toString←stringにする例ですが)。 と同じです。 http://java.sun.com/javase/ja/6/docs/ja/api/java/lang/Integer.html#doubleValue()
関連するQ&A
- Java 可変長引数と優先度
Java 可変長引数と優先度 こんにちは。c#初心者兼、java始めました です。 可変長引数の場合のオーバーロードの優先度について困っています(質問と言うより半分愚痴です)。 javaにも可変長引数ってありますよね。(ジェネリックの弱さにイライラしていたけれど)「javaも捨てたものじゃない」と感心しながら使っていると、いきなりコンパイルエラー。 sampleMethod(10, 20); と書いている部分でエラーが発生していました。 自分のメソッド定義を確認しみると、 void sampleMethod(int...); void sampleMethod(Object...); の2種類のオーバーロードがあり、ambiguousなため判別不能らしいです。 確かに、AutoBoxingされれば、int...だけでなく、Object...にもマッチしますが、どう考えてもBoxingしない方が優先度が高いはずです。というか、高く設定されるべきです。 個人的に基準にしているc#ではこのようなことは起きませんでした。 (あ、やっぱり捨てたものかもしれない ←心変わり早す(ry ) 試しにc#でInteger型のクラスを作り、(実際はタブーですが)暗黙のキャストを双方向でオーバーロードして実験してみました。 public class Integer // ここからc# { private int _value; //---------------------------- public Integer(int value) { _value = value; } //---------------------------- // Integer → int の暗黙の型変換 public static implicit operator int(Integer value) { return value._value; } // int → Integer の暗黙の型変換 public static implicit operator Integer(int value) { return new Integer(value); } //---------------------------- // javaの sampleMethod(int... values)に相当 public static void SampleMethod(params int[] values) { } // javaの sampleMethod(Object... values)に相当 public static void SampleMethod(params Object[] values) { } } そして、Integer.SampleMethod(10, 20); と書いてみると……問題……なし。 ちゃんと、SampleMethod(param int[] values)が選ばれていました。 つまり、(個人的には)java(コンパイラ)の方が不可解な動きをしているのです。 sampleMethod(int, int)とsampleMethod(Object, Object)があるときは問題ないので、可変長引数のときだけambiguousになるようです。 「それなら」と思い、sampleMethod(int, int...)とsampleMethod(Object, Object...)を作ってみましたが、やはりエラーが出ます。 何か良い解決策はあるでしょうか? 可変長じゃない引数のオーバーロードを大量に作ることと、片方の可変長をやめること以外でアドバイスをお願いします。 もしくは、「個人的には~だから、パクリのc#よりjavaの方が動きが正しいぞ!」という方がいらっしゃいましたら、ご意見ください。
- 締切済み
- Java
- Javaの質問です。
データに0より小さい数値がある場合、その行を取り除いて集計させ、エラーがある行だけを別ファイルに書きだしたいのですが、うまくいきません。 なにかアドバイスいただけますでしょうか? よろしくお願いします。 import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileReader; import java.io.FileWriter; import java.io.PrintWriter; class Data { double value; Data(double value) { this.value = value; } void setData(double value) { this.value = value; } public String toString() { return String.format("%5.1f", value); } } class Statistics { Data min = new Data(999.9); Data max = new Data(0.0); double total = 0.0; void add(double value) { if (min.value > value) { min.setData(value); } if (max.value < value) { max.setData(value); } total += value; } } class Category { String category; Statistics height = new Statistics(); Statistics weight = new Statistics(); Statistics bmi = new Statistics(); int num = 0; Category(String category) { this.category = category; } void add(double height, double weight) { this.height.add(height); this.weight.add(weight); this.bmi.add(weight / (height / 100.0 * height / 100.0)); num++; } public String toString() { return category + "," + "身長" + "," + "最高" + "," + height.max + "\n" + category + "," + "身長" + "," + "最低" + "," + height.min + "," + "\n" + category + "," + "身長" + "," + "平均" + "," + String.format("%5.1f\n", height.total / num) + category + "," + "体重" + "," + "最高" + "," + weight.max + "," + "\n" + category + "," + "体重" + "," + "最低" + "," + weight.min + "\n" + category + "," + "体重" + "," + "平均" + "," + String.format("%5.1f\n", weight.total / num) + category + "," + "BMI" + "," + "最高" + "," + bmi.max + "\n" + category + "," + "BMI" + "," + "最低" + "," + bmi.min + "\n" + category + "," + "BMI" + "," + "平均" + "," + String.format("%5.1f\n", bmi.total / num); } } class Health { Category male = new Category("男"); Category famale = new Category("女"); Category total = new Category("全体"); void add(String sex, double height, double weight) { if (sex.equals("男")) { male.add(height, weight); } else { famale.add(height, weight); } total.add(height, weight); } public String toString() { return "" + male + "\n" + famale + "\n" + total + "\n"; } } public class Main { static final String FILENAME = "hw.csv"; static final String SEPARATOR = ","; static final int SEX = 2, HEIGHT = 3, WEIGHT = 4; public static void main(String[] args) throws Exception { Health health = new Health(); String line; BufferedReader file = new BufferedReader(new FileReader(FILENAME)); for (int number = 1; (line = file.readLine()) != null; number++) { String[] item = line.split(SEPARATOR); try { if(Integer.parseInt(item[HEIGHT]) <= 0 || Integer.parseInt(item[WEIGHT]) <= 0 || item[HEIGHT] == null || item[WEIGHT] == null) { PrintWriter pw = new PrintWriter( new BufferedWriter (new FileWriter("out_error.csv"))); pw.println(number); pw.close(); health.add(item[SEX],Double.parseDouble(item[HEIGHT]),Double.parseDouble(item[WEIGHT])); } } catch (Exception e) { } } file.close(); PrintWriter pw = new PrintWriter( new BufferedWriter (new FileWriter("out.csv"))); pw.println(health); pw.close(); } }
- 締切済み
- Java
- Javaのプログラムについて教えて下さい
//Sample.java class Sample void methodA(int temp) if(temp == 0) String str = new String("Exception"); Integer.parseInt(str); else if(temp == 1) int[] array = new int[temp]; else Exception exc = new Exception(); throw exc; //SampleMain.java class ExceptionMain public static void main(string[] args) Sample sam = new Sample(); Int temp = Integer.parseInt(args[0]); Sam.method(temp); } } このプログラムの場合、ExceptionMainに新たにコードを加えて、コマンドライン引数が0,1,その他の場合に例外メッセージを出力するプログラムを教えて下さい。
- ベストアンサー
- Java
- PHPのpack関数をJavaで実装できるのでしょうか
PHPで文字列を16進バイナリ文字列に変換する関数であるpack関数というものがありますが、これと全く同じ動きをしてくれるメソッドがjavaには存在しないようです。これを自分で実装する方法をあれこれ考えているのですが、どうしてもうまくいきません。 下のようなメソッドを作ってみたのですが、戻ってくるのはただの数値文字列です。 /** * @param toPack バイナリへの変換対象の数値 */ String getHexBinary(int toPack){ String buf = ""; String hex = Integer.toString(toPack, 16); char decChars[] = hex.toCharArray(); for(int decChar : decChars){ buf += Integer.toHexString(decChar); } return buf; } PHPのpack関数はこの戻ってくる数値文字列を何らかの手法で結合しているように見えるのですが、その挙動が理解できずに困っています。どなたか、ご教授願えないでしょうか。ちなみに、Javaのバージョンは5.0でやっています。PHPのバージョンは5.2です。
- ベストアンサー
- Java
- 配列の型判定の仕方
メソッドの引数をObjectにして、その引数の型を判定しようとしています。 たとえば以下のような感じです。 String hoge(Object para) { if(para.equals(java.lang.Integer.class)) { return "intです"; } return "わかりません" } 上記は、int型なら判定できるメソッドですが、int[]やString[]を判定するためにはどうしたらよいのでしょうか? paraにint[]型の値が入ってきた場合、 para.equals(java.lang.Integer[].class) としてもtrueにはなりませんでした。 どうすればできるのか、ご教授いただけると幸いです。 手段がなければ、para.getClass().toString()をして出力される文字列で判定しようかと思っています。
- ベストアンサー
- Java
- Javaを始めたばかりなのですが、どうしたら向上できるでしょうか?
これからSEとして働いていく者です。 会社の研修でJavaを学んでいるのですが、難しいと感じています。 特に、クラス間をまたいで引数やメソッドを指定することが苦手です。 何を当てはめたらいいのかわからなくなります。 それから、「キャスト」というのもよくわかりません。 「String型」や「int型」ならわかるのですが、自分で型を考えねばならないときは、それ自体思いつかないことが多いです。 人に教えてもらえば「そういうことか」と理解できるのですが、自分で考えるとすぐ壁にぶつかってしまいます。 どのような勉強をすればこのようなことを克服し、レベルアップしていけるでしょうか?
- ベストアンサー
- Java
- Javaのオーバーライドについて教えてください!
//Sample.java class A extends Fina{ public int part(String str1,String str2){ int iN1 = Integer.parseInt(s1); int iN2 = Integer.parseInt(s2); intNum1 *= intNum2; return intNum1; } } このプログラムに対応するように同じクラス内でオーバーロードした際のプログラムを教えてください。 オーバーロードの内容は、partメソッドをオーバロードして引数にString型のデータを二つ受け取り、2つのString型のデータをそれぞれint型に変換し、それぞれかけた値を別のクラスでメインから呼び出すにはどうすれば良いですか?
- ベストアンサー
- Java
- Javaの配列の宣言方法のメリット?
1週間ほど前からJavaを独学している者です。 C言語をその前からやっていて、初心者レベル程度ならわかると思います。 そこで、質問です。 C言語の配列宣言: int array[10]; Javaの配列宣言: int array[] = new int[10]; 二つの言語とも、要素10個のarray1次元配列変数を宣言していると思います。 C言語の書き方はシンプルなので、納得がいきますが、Javaの方はどうしてこの形で宣言をするのかわかりません。(自分が言語製作者ならシンプルな書き方を採用します) だから、このような宣言の方法をとるということは何か理由があるのだと思います。 自分が思うところ、JavaはC言語より、柔軟で多機能だとおもうので、その影響で汎用性をますために、 長くなっているのかな~?と思っています。 こんごJavaの学習を進めていくと、例えば、 int array[] = new double[10]; //←エラーになりました みたいに型のちがう、宣言が出てきたりするのでしょうか? ちらっと、学習に使っている本をみたところ、動的配列の作成は別の操作で実現しているようなので、 「動的とは関係ないのかな?」と思っています。 長くなりましたが、Javaの配列宣言のメリットを教えてください。
- ベストアンサー
- Java
- C#で実行時にメソッドの返り値の型を変化させる
C# で、実行時にメソッドの返り値の型を変化させることは可能でしょうか? たとえば、 public class MyData { object o; public void setValue( object a ) { o = a; } public object getValue() { return o; } } というクラスがあるとき、 static void Main(string[] args) { MyData a = new MyData(); a.setValue( 3 ); Console.WriteLine( a.getValue().GetType().ToString() ); int i = (int)a.getValue(); } というコードを実行すると、 System.Int32 と表示されます。Main の 4 行目で、(int)のキャストをはずすと、object から int への暗黙の変換はできませんというコンパイルエラーになります。 この(int)のキャストをしなくてもエラーにならないような getValue の関数はできないでしょうか? o は、数値型であるとします。 たとえば、MyData に、 public int getInt() { return (int)o; } とすれば、必ず int を返すようなメソッドはできると思うのですが、これだと、getByte() や、getDouble() などのように、考えられるすべての型を想定してメソッドを作ることになってしまいます。 そうではなく、getValue() で、少なくとも数値型の暗黙の変換はしてくれるようなことにできないでしょうか。 よろしくお願いします。
- ベストアンサー
- C・C++・C#
- javaにおけるサブプロセスの待ち方
以下のコードで問題が起きました。 javaからサブプロセスを読んで、サブプロセスの標準出力から 文字列を取得するプログラムです。 //Inter.java import java.io.*; public class Inter { static final int A = 10; public static void main(String[] arg) { String out = "Initial"; int c; Runtime rt = Runtime.getRuntime(); try{ Process ps = rt.exec("process.exe"); BufferedReader br = new BufferedReader(new InputStreamReader(ps.getInputStream())); System.out.println("Debug:OK"); for(c=0;c < A;c++)//ポイント1 { out = br.readLine(); System.out.println("java:" + out); } out = Integer.toString(ps.waitFor());//ポイント2 System.out.println("終了コード:" + out); }catch(Exception ex){ System.out.println("エラー"); } System.out.println("正常終了"); } } 一方呼び出されるサブプロセスは //process.c //compiled to process.exe #include <stdio.h> int main () { int i,k,n; for(i=0;i<100;i++) { printf("test%d\n",i); } return 235; } ここで、java側のコードの定数Aを1以上に設定るると期待どおりの結果が出るのですがA=0つまり、for文に一度も入らず、標準出力のストリームから文字列を一度も読まないとフリーズします。どうやら out = Integer.toString(ps.waitFor());//ポイント2 の部分で止まるようです。これはなぜでしょうか?これでは、標準出力があるサブプロセスの終了コードだけ知りたい時に不便ではないですか?これはもしやjava言語システムのバグではないでしょうか!waitFor()メソッドの実装が観たいのですがあいにくnativeキーワードがあるメソッドで手元のソースだけではでは中身がわかりません。nativeのさらに中の実装は見ることはできないのでしょうか?
- ベストアンサー
- Java