ジェネリックスに関するプログラムでのコンパイルエラー

このQ&Aのポイント
  • ジェネリックスを使用したプログラムで、コンパイルエラーが発生しました。
  • エラーメッセージによると、名前の競合が原因で、オーバーライドができないとされています。
  • このエラーの解決策として、TがStringであることを明示することが挙げられます。
回答を見る
  • ベストアンサー

ジェネリックスに関して

次のようなプログラムを書きました。 class A<T> {  public String display(T t) {   return t.toString();  } } public class Test extends A<String> {  public String display(Object o) { //ここでコンパイルエラー   return o.toString();  }  public static void main(String[] args) {   Test test = new Test();    test.display("hello, world");  } } 上で示した部分でコンパイルエラーが出ました。エラー内容は 名前の競合:型Testのメソッドdisplay(Object)は型A<T>のメソッドdisplay(T)と同じerasureを持っていますが、オーバーライドしません。 というものでした。この場合、 public class Test extends A<String> と、TがStringであることを明示しているので、このプログラムではdisplay(Object)はdisplay(T) をオーバーロードしているのではないのでしょうか。 もしくは、もしdisplay(Object)とdisplay(T)が同じerasureを持っているなら、それでオーバーライドしていることにはならないのでしょうか?

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

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

  • ベストアンサー
  • kana_m
  • ベストアンサー率40% (26/65)
回答No.1

単純にイレイジャが何かを理解していないのだと思います。 ジェネリクスの型は、型情報として残す必要がないためコンパイル時に消えます。 つまり、実際にはメソッドの引数はオブジェクト型として扱われます。 display(Object)がdisplay(T)をオーバーロードできないのはこのためです。

pikacha
質問者

お礼

回答ありがとうございます。 イレイジャについてもっと勉強してみます。 ありがとうございました。

関連するQ&A

  • java ジェネリックスに関して

    以前にも似たような質問をしたことがありますが、それに関しての質問です。 次のようなプログラムを書きました。 class A<T> {  public void display(T t) {   System.out.println("A class");  } } public class Test extends A<String> {  public void display(Object t) {    //問題の行   System.out.println("Test class");  }  public static void main(String[] args) {     } } 上記の問題の行のところでエラーが出ました。 名前の競合: 型 Test のメソッド display(Object) は型 A<T> の display(T) と同じ erasure を持っていますが、オーバーライドしません A<T>のメソッドdisplay(T)のerasureはdisplay(Object)になるので、display(T)は確かにTestのメソッドdisplay(Object)と同じerasureを持っています。しかしそうなると、Testのdisplay(Object)のシグネチャがA<T>のメソッドdisplay(T)のシグネチャのerasureと同じになるため、オーバーライドできることになると考えたのですが、コンパイル結果はエラーとなってしまいました。 どうしてオーバーライドできないのでしょうか。 例えば public class Test extends A<String> を public class Test<T> extends A<T> にかえた場合はうまく行きました。従ってTをStringと指定しているところに問題があると思うのですが、どうしてコンパイルできないのでしょうか。 また、Testのdisplay(Object)をdisplay(String)にかえた場合(このとき、他の部分ははじめのプログラムと同じ)、A<T>クラスのdisplay(T)をオーバーライドできました。今度はTestクラスのdisplay(String)とA<T>クラスのdisplay(T)はerasureが同じではないので、オーバーライド等価ではない、従ってオーバーライドできないと思ったのですが、どうしてオーバーライドできるのでしょうか。

    • ベストアンサー
    • Java
  • コンパイルエラー(匿名クラス)

    下記ソースがコンパイルエラーを起こしてどうしたらよいか分かりません。 下記エラー参照 Main.java:2: 型の開始が不正です。 new String(){ ^ Main.java:6: <identifier> がありません。 };ん。 (下記ソース) class NormalClass{ new String(){ public String ToString(int n){ return n + ""; } }; } class Main{ public static void main(String args[]){ NormalClass test = new NormalClass(); System.out.println(test.ToString(10)); } }

    • ベストアンサー
    • 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() で、少なくとも数値型の暗黙の変換はしてくれるようなことにできないでしょうか。 よろしくお願いします。

  • Javaのプログラムについて至急教えてください!

    //Sub.java class Super{ public void A(){} } class Sub extends Super{ /* (1) */ } このプログラムの(1)に入るものを下から2つ選んで他のクラスのメインメソッドから呼び出すのですがどうやってもわかりません。わかる方教えてください! public void A(){} public String A(){ return "pool";} public int A(String str){return Integer.parseInt(st);} public int A(){return 3;} public Object A(){return new Object();}

    • ベストアンサー
    • Java
  • コンパイルエラー(Threadオブジェクト化)

    Runnableを継承したNormalClassをThreadとしてオブジェクト化しようとしているのですが、コンパイルエラーが出現して困っています。どうすればいいでしょうか? 下記エラー参照 Main.java:1: NormalClass は abstract でなく、java.lang.Runnable 内の abstract メソッド run() をオーバーライドしません。 下記ソース class NormalClass implements Runnable{ } class Main extends Thread{ public static void main(String args[]){ test = new Thread(new NormalClass()); } }

    • ベストアンサー
    • Java
  • インスタンスの情報表示について

    Java初心者です。 例えば次のようなソースがあって、double型の変数numの情報を表示するためにtoStringをオーバーライドするとすると、どのようにすればStringを返せるのでしょうか。 public class Test { private double[] num; public Test(double a, double b, double c) { num = new double[3]; this.num[0]=a; this.num[1]=b; this.num[2]=c; } public toString() { // return "インスタンスは: "+ } public static void main(String args[]) { Test a = new Test(4.3, 5.6, 12.7); System.out.println(a.toString()); } }

  • 配列の型判定の仕方

    メソッドの引数を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
  • 敬称について教えてください

    class parent{ protected final static int val=10; } class Child extends Parent{ private int val=100; public void method(String s){ System.out.println(++val)} } } class Test{ int val=10; public static void main(String args[]){ Parent c=new Child(); c.method("HELLO"); } } 初歩的な質問ですみません。教えて下さい。 上記プログラミングで、下から3行目のc.method・・・ を記入してもコンパイルエラーがおこらないのはなぜでしょうか? 今回newしているのはChildのオブジェクトです。 が、型はParentです。 Parentにはmethodはないし、 なぜこれが許されるのかがわかりません。 分かりやすくおしえてもらえませんか?

    • ベストアンサー
    • Java
  • javaのオーバーライドについての質問です。

    *  クラスParent04に受け取ったString配列の中身を全て大文字に変換するChangeメソッドが定義されています。クラスParent04を継承するクラスChild04でChangeメソッドを  オーバーライドして、String配列の中身を全て小文字に変換するように変更してください。  その後クラスOverRide04のmainメソッドからChangeメソッドを呼び出して、  変換後のString配列の要素を全て出力してください。 */ // オーバーライドされるので覆い隠される class ORParent04{    public String[] Change(String[] strArray){       int len = strArray.length;      String[] Array = new String[len];      for(int i = 0; i < len; i++){       Array[i] = strArray[i].toUpperCase();      }      return Array;   } } // ORParent04クラスを継承し、ORChild04でオーバーライド // こちらが適用される。 class ORChild04 extends ORParent04{    //ここからプログラムを追加してください。    public String[] Change(String[] strArray){       int len = strArray.length;       String[] Array = new String[len];       for(int i = 0; i < len; i++){                   // toLowerCaseで小文字に変換         Array[i] = strArray[i].toLowerCase();       }       // 値を返す       return Array;    } } class OROverRide04{   public static void main(String[] args){        // ORChild04クラスのインスタンス化     ORChild04 ORchild04 = new ORChild04();       //ここからプログラムを追加してください。     // Changeメソッドの呼び出し:戻り値String[],引数String[]      String[] array = ORchild04.Change(String[] args);          // 表示      System.out.println(array);   }  } このような問題で、現在これをコマンドプロンプトでコンパイルすると、mainメソッド内のString[] array = ORchild04.Change(String[] args);メソッド呼び出し部分が指定され、 「'.class'がありません」 「;がありません」 という2つのエラーが表示されます。ネットでエラー表記の意味を検索し、コードを確認しましたが、「{}」と上記より上の行の;が特に抜けている、という訳ではありません。勿論自分が何か見落としている為にコンパイルエラーになるのですが、戻り値と引数の値は合わせているので、心情としては「動けジ・O!何故動かん!?」という具合です。 どなたか考え方やヒントなどお願い致します。後もう少しだと思うのですが。。。

    • ベストアンサー
    • Java
  • GetterとSetterをやったのに。

    以下のプログラムを実行すると、フィールドA.aは不可視です。メソッドtestは型Aで不可視です。というエラーが出てきます。本に書いてあるとおり、やったのですが、どうしてダメなのかわかりません。ぜひ教えてください。 public class Sample { public static void main(String[] args) { A aa=new A(); System.out.println(aa.a); aa.test(); } } class A{ private String a = "A"; private void test(){ System.out.println("Test"); } public String getA() { return a; } public void setA(String a) { this.a = a; } }

    • ベストアンサー
    • Java

専門家に質問してみよう