• ベストアンサー

[Java1.5]Genericsとオーバーロード

現在、Eclipseの上でJavaプログラミングを行っています。 ところが、オーバーロードを行う際にエラーとなり困っています。 疑問点と、解決策をお聞きできるとありがたく思います。 あるプログラムで、単純に言うと以下のようなオーバーロードを行いました。 public static String theFunction(Map<Integer, Integer> theMap){       ・・・ } public static String theFunction(Map<Integer, String> theMap){       ・・・ } すると、一つ目のメソッドに対し Duplicate method theFunction(Map<Integer, Integer> theMap) in ... 二つ目のメソッドに対し Duplicate method theFunction(Map<Integer, String> theMap) in ... というエラーが出てしまいました。 こういうものなのでしょうか? つまり、同じ型のGenericsは、その要素の型が違っていても同一視されるのでしょうか。 またその場合、代替策は無いでしょうか? つまり、 theFunction(x); とした時、x が Map<Integer, Integer> か Map<Integer, String> かによって処理を変える良い方法は無いでしょうか? よろしくお願い致します。

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

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

  • ベストアンサー
  • bgbg
  • ベストアンサー率53% (94/175)
回答No.2

Genericsはコンパイル時の型チェックまでで、実行時には失われてしまいます。 なので、コンパイル後のtheFunctionは両方とも theFunction( Map theMap ) として扱われます。 代替策としては、MapのValue値の型を見て処理を振り分ける、くらいでしょうか。 public static String theFunction(Map theMap){ Set keySet = theMap.keySet(); for ( Object key : keySet ) { Object value = theMap.get( key ); if ( value instanceof Integer ) { theFunction_inner_Integer( key, value ); } else if( value instanceof String ){ theFunction_inner_String( key, value ); } }    :    : }

elmsley
質問者

お礼

Genericsは、そういうものだったんですね…。 himajinさんに頂いた回答とあわせ、理解できました。 コードまで書いて頂き、有難うございます! 参考にさせていただきます。

その他の回答 (1)

回答No.1

http://www-06.ibm.com/jp/developerworks/java/050218/j_j-jtp01255.html とりあえず俺は今ひとつ理解できてないような気がするが 参考にはなりそうだと思ったんで投稿。 こっちは読んですらいない http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=34513&forum=12&5

elmsley
質問者

お礼

ありがとうございます! >こっちは読んですらいない の方と、そこからのリンクで理解できました。 そもそも、Genericsの存在理由がよく分かっていなかったようです。

関連するQ&A

  • オーバーロードの「あいまい」エラーについて

    お世話になっております。 メソッドのオーバーロードにおいて、以下の様な場合にコンパイルエラーが発生します。 環境:JDK1.6.0_13 + eclipse3.3.2 public class Sample { static void meth(long... longs){ System.out.println("long..."); } static void meth(Integer... Integers) { System.out.println("Integer..."); } public static void main(String[] args){ meth(100); } } エラーメッセージ:メソッド meth(long[]) は型 Sample であいまいです (以下、「あいまいエラー」と表記します) 今回のケースでは、なぜこの様なエラーが出てしまうのか、今一つわからずに困っています。 「あいまいエラー」について少し調べを入れてみましたが、 参照型を引数に取るメソッドが複数ある時にnullを渡した時など、 明瞭にわかりやすいケースの例示は見つかったのですが、 今回の様なケースに当てはめて納得の行く情報ソースは見つけられませんでした。 まとめますと、私の欲しい情報は、 可変長引数リストを引数に取るオーバーロードメソッドが複数ある時に、 「あいまいエラー」が発生する規則です。 以上です。よろしくお願いします。

    • ベストアンサー
    • Java
  • Generics extends ObjectとObjectの違い

    初めて質問させていただきます。 Generics(extendsの?)の考え方についてです。 例えば、下記のような関数を作成したとします。 ======================================= public static String getHoge(Map<String , ? extends Object> checkMap){   Set<Map.Entry<String, Object>> checkMapKeySet = checkMap.entrySet();   ~ 処理 ~ } ======================================= 2行目で「型の不一致: Set<Map.Entry<String,capture#3-of ? extends Object>> から Set<Map.Entry<String,Object>> には変換できません。」とコンパイラから怒られます。 では、Objectの派生クラスをObjectとして扱えないのかと単純に理解しようとすると、以下のコードは普通にコンパイルできてしまいます。 ======================================= public static String getHoge(Map<String , ? extends Object> checkMap){   for(Map.Entry<String, ? extends Object> checkMapEntry : checkMap.entrySet()){     Object obj = checkMap.get("aa");     ~ 処理 ~   } } ======================================= 最初のコードがエラーになるなら、2つ目のコードの3行目(Object obj =の行)が何故エラーにならないのか、その違いをどのように解釈していいのか悩んでいます。 ご存じの方がいらっしゃいましたら、アドバイスでもいただけると幸いです。

    • ベストアンサー
    • Java
  • 問題の解説お願いします。(オーバーロード&オーバーライド)

    class A{ protected int method1(int a , int b){ return 0; } } クラスAを継承したクラスで同時に定義できるメソッド が、 public int method1(int a,int b){return 0;} が良くて private int method1(int a,int b){return 0;} static protected int method1(int a,int b){return 0;} がだめな理由がいまいちわかりません。 法則みたいなものにこう書いてありました。 (オーバーロードについて) 同一クラス内に同一名称のメソッドを定義することができます。 ただし、それらは引数が異なるものでなければならず、 アクセス制御修飾子や戻り値の型だけが異なるメソッドは 定義することができません。 (オーバーライドについて) サブクラスでは、スーパークラスに存在するメソッドと同一引数・ 同一戻り値型を持つメソッドを定義することが許されています。 これら以外にも何か決まりがあるのでしょうか よろしくお願いします。

    • ベストアンサー
    • Java
  • オーバーロードで

    オーバーロードでメソッドgetvalueへコマンドライン引数から取得した値を渡したいのですが、どのようにすればいいのでしょうか。エラー:シンボルが見つけられません。 ×としたところでol.getvalue( args[i] );←ここに値をいれたいのですが、できません。なにか方法はありますでしょうか。 class OverLoad{     void getvalue(Boolean value){   System.out.println("Boolean型:" + value);     }     void getvalue(int value){   System.out.println("int型:" + value);     } public class Capsule{     public static void main(String[] args){   OverLoad ol = new OverLoad(); ×   ol.getvalue( args[i] ); ○   ol.getvalue(false); ○     ol.getvalue(80);     } }

  • java これはオーバーロードすればいいのでは?

    以下のようなコードについて質問です。 class Person { public static int count = 0; public String firstName; public String middleName; public String lastName; public int age; public double height; public double weight; Person(String firstName, String lastName, int age, double height, double weight) { Person.count++; this.firstName = firstName; this.lastName = lastName; this.age = age; this.height = height; this.weight = weight; } Person(String firstName, String middleName, String lastName, int age, double height, double weight) { this(firstName, lastName, age, height, weight); this.middleName = middleName; } public String fullName() { if(middleName == null){ return this.firstName + " " + this.lastName; }else{ return this.firstName + " "+middleName+ ""+ this.lastName; } } fullName() メソッドを条件分岐して、以下のようなメソッドで、ミドルネームを入れるかどうかで、条件分岐するということなのですが… class Main { public static void main(String[] args) { Person person1 = new Person("Kate", "Jones", 27, 1.6, 50.0); person1.printData(); Person person2 = new Person("John", "Christopher", "Smith", 65, 1.75, 80.0); person2.printData(); Person.printCount(); } } これって、引数にfullNameメソッドに何も指定してなくていいのでしょうか。 疑問に感じてしまいました。 また、同じfullNameメソッドという名前のメソッドで引数でmiddleNameの有無だけ変えてオーバーロードしてはだめなのでしょうか。

  • C#における++演算子のオーバーロードについて

    はじめまして。 いろいろ調べてみたのですが、わからなかったので、質問させてください。 C#における++演算子のオーバーロードについてなのですが、 まずは、以下のコードをご覧ください。 ================================================================ using System; class Test { private int Num; public Test(int x) { this.Num = x; } public static Test operator ++(Test t) { Test result = new Test(t.Num + 1); return result; } public override string ToString() { return this.Num.ToString(); } } class TestDemo { public static void Main() { Test t = new Test(0); Console.Write(t++ + "\n"); Console.Write(t + "\n"); Console.Write(++t + "\n"); Console.Write(t + "\n"); } } ================================================================ 実行結果 0 1 2 2 ================================================================ ++演算子のオーバーロード関数の実装が一つなのに 前置インクリメントと後置インクリメントが適切に行われています。 二つのインクリメントが行われるときに同じメソッドが 呼び出されていると思うのですが、同一の実装で、振る舞いが 異なるのは、なぜなのでしょうか?どのようなカラクリで 実行されているのでしょうか?全くわかりません。どなたか 教えてください。よろしくお願いします。

  • Integerについて

    class Sample5_7_Integer { /** * Integerクラスのメソッド */ public static void main(String[] args) { //String → int int i1 = Integer.parseInt(args[0]); //int型にすることにより計算可能 System.out.println(i1 + 100); //String → integer Integer i2 = Integer.valueOf(args[0]); System.out.println(i2); Integer i3 = new Integer(100); System.out.println(i2.equals(i3)); } } をEclipseで実行したところ、 Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0 at benkyou.Sample5_7_Integer.main(Sample5_7_Integer.java:10) というエラーになってしまいます。 どなたか解決法をお願いします。

    • ベストアンサー
    • Java
  • コンストラクタのオーバーロードについて

    class loo{ //フィールドの定義 int sland; //コンストラクタの定義1 loo(){ this.sland = 28; } //コンストラクタの定義2 loo(int sland){ this.sland = sland; } //メソッドの定義 void ken(){ System.out.println(this.sland); } } //mainメソッド class kkk{ public static void main(String args[]){ ---------------------------------------------- loo lo = new loo(); lo.ken(); lo.ken(100); ---------------------------------------------- } } コンストラクタのオーバーロードについて、伺いたいことがありますので掲載致しました。 今回は、kenメソッドを用いて変数slandに入っている値を表示するプログラムを作りたいと思っています。 コンストラクタのオーバーロードを利用するわけですが、プログラム実行後に 28 100 という風な出力結果を得ようと、上記のようなプログラミングを実施しました。 しかし、いざコンパイルをかけると java:27: ken() (loo 内) を (int) に適用できません lo.ken(100); ~ というエラーが表示されてしまいます。 ----でかっこってある部分に問題があるのはわかっているのですが、思うように結果を得ることができない状況です。 また、----の部分を、 loo lo = new loo(100); lo.ken(); lo.ken(); と、書き換えると出力結果は 100 100 と表示され、28が表示されなくなってしまいます。 お手数ですが、ご教授の程お願い致します。

  • javaのGenericsが良く分かりません

    かなり以前に java プログラミングを少しばかりやっていたので java は少し分かるのですが、最近 また java プログラミング始めてみたのですが、Generics なる機能が「Java SE5.0から導入されたようですが、良く分かりません。 ご存知の方がいらしたら どうか ご教授下さいませm(_ _)m 開発環境 eclipse java 8 class Box<T> { // Object obj; T obj; @SuppressWarnings("unchecked") public T getT(){ return obj; } public void setT(T o){ obj = o; } @SuppressWarnings("unchecked") public void setTExtends(Box<? extends T> o){ obj = (T)o; } } Box<Number> boxN = new Box<Number>( ); Box<Integer> boxI = new Box<Integer>( ); boxN.setT((Number)new Integer(1)); // 当然、正常にコンパイルされる。 boxN.setT(new Integer(1)); // なぜか正常にコンパイルされる。 boxN.setT(boxN.getT()); // 正常にコンパイルされる。 boxN.setT(boxI.getT()); // なぜか正常にコンパイルされる。 boxN.setTExtends((Number)new Integer(1)); // なぜかコンパイル・エラーになる。 boxN.setTExtends(new Integer(1)); // なぜかコンパイル・エラーになる。 boxN.setTExtends(boxN.getT()); // なぜかコンパイル・エラーになる。 boxN.setTExtends(boxI.getT()); // なぜかコンパイル・エラーになる。 boxI.setT(new Integer(1)); // 当然、正常にコンパイルされる。 boxI.setT(boxI.getT()); // 当然、正常にコンパイルされる。 boxI.setTExtends(new Integer(1)); // なぜかコンパイル・エラーになる。 boxI.setTExtends(boxI.getT()); // なぜかコンパイル・エラーになる。

  • コンパイルできません

    Javaを独習中の、初心者です。何方か、教えてください。 或る入門書で、「メソッドのパラメター化」との項目の中に、下記 サンプルプログラムが載っておりまして、その通りに、入力実行しましたが、「Generics.java:5: ';'がありません。return T.toString() data;」とのエラーメッセージが表示され、試行錯誤してみましたが、解りません。何処が、エラーなのかお教え頂ければ幸いです。 1 import java.util.Data; 2 3 class Generics { 4 public static <T> String geneMethod( T data ) { 5 return T.toString() data; 6 } 7 8 public static void main( String[] args ) { 9 String str = 10 Generics.<String>geneMethod("aaa"); 11 System.out.println( str); 12 Data data = 13 Generics.<Data>geneMethod( new Data()); 14 System.out.println( data ); 15 } 16 } 以上、宜しくお願い致します。  

    • ベストアンサー
    • Java

専門家に質問してみよう