• ベストアンサー

ジェネリクスとワイルドカード型

amanojaku1の回答

  • ベストアンサー
回答No.1

>class TestTest<T extends Number> { >ㅤList<? extends Number> list; >} まず、「class TestTest<T extends Number>」と「List<? extends Number> list;」の意味が違います。 「class TestTest<T extends Number>」はクラスの定義で、「<T extends Number>」は「型変数の宣言」です。 「List<? extends Number> list;」はオブジェクト変数の生成で、「<? extends Number>」は「型変数へのバインド」です。 なので下記のようにオブジェクト変数「list」にインスタンスを代入する事が可能です。 import java.util.List; import java.util.ArrayList; ~ class TestTest<T extends Number> { List<? extends Number> list = new ArrayList<Number>(); } >class TestTest<? extends Number> { >ㅤList<T extends Number> list; >} ここからは推測です。 >class TestTest<? extends Number> { ↑クラスの定義では「<? extends ~>」、「<? super ~>」、「<?>」は使えないと思われる。 >ㅤList<T extends Number> list; ↑オブジェクト変数の生成では「<T extends Number>」、「<T super Number>」は使えないと思われる。 クラスで仮型パラメータ「T」が設定されてないなら「<T>」はエラーになる。 クラスで仮型パラメータ「T」が設定されているなら、コンパイル時に「T」は実型パラメータとなるので「<T>」はエラーにならない。

oilon11
質問者

お礼

参考書の説明が超絶雑すぎて、総称型はextendsが使えて、ワイルドカード型はsuperも使えるくらいしか書いてなかったので参考になります。「型変数の宣言」と「型変数のバインド」って初めて聞きました。

関連するQ&A

  • 総称型のキャストでエラー

    下の書き方で、※1はエラーにならないのですが ※2ではエラーになります。 ※1がキャスト可能であれば、 ※2も可能だとおもうのですが。 Java7を使っています。 public class Soushou { void test() { List<Kodomo> kodomoList = new ArrayList<Kodomo>(); List<? extends Oya> oyaList = kodomoList; Object o1 = (List<Oya>) oyaList; // ※1 エラーにならない。 Object o2 = (List<Oya>) kodomoList; // ※2 「キャストすることができません」エラーになってしまう。 } } class Oya { // 親クラス } class Kodomo extends Oya { // 親クラスを継承した子クラス }

    • ベストアンサー
    • Java
  • 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
  • Accessで差分取得する方法は? LEFT JOIN エラー

    Accessで差分抽出するSQLを教えてください。 【旧テーブル】t1 id, class, number, value 1, "a", 1, "aka" 2, "a", 2, "aki" 3, "a", 3, "aku" 【新テーブル】t2 id, class, number, value 1, "a", 1, "aka" 2, "a", 2, "更新" 3, "a", 3, "aku" 4, "a", 4, "新規" 5, "b", 1, "新規" 【ダメだったクエリ】 SELECT t2.* FROM t2 INNER JOIN t1 WHERE t1.class IS NULL OR t1.number IS NULL 【望む結果】 4, "a", 4, "新規" 5, "b", 1, "新規" *列 id は各テーブルの主キーですが、新旧テーブル間の関連はありません(リレーションではありません)。

  • 「オブジェクト志向」の考えかたで質問します。

    「オブジェクト志向」の考えかたで質問します。 いろいろと調べると、 ・繼承 ・カプセル化 ・ポリモーフィズム を総称したのが、「オブジェクト」志向と理解しています。 このとき、 たとえば、 指定するクラスの生徒の情報をとりだすようなソースをつくりたい。 仮に、以下をかんがえてみました。 DB処理は、省いてます。 //実行DAOクラス public class StudentDAO extends StudentDBAccessor{ //指定するクラスに属する生徒をとりだす public List getStudentList(int classNumber){ return super.getStudentList(); } //sql文生成 protected String createSqlSelectStudentList(){ StringBuffer sb = new StringBuffer(); return sb.toString(); } //キーワードを設定 public void setDataSqlStudentList(){ } } public abstract StudentDBAccessor extends DBConnector{ protected List getStudentList(){   //DBそうさ } protected abstract String createSqlStudentList(); protected void setDataSqlStudentList(int classNumber); } //DB接続クラス public class DBConnector{   //省略 } //Beanクラス public class StudentFormBean{ private int studentNumber; private String studentName; public void setStudentNumber(int number){ this.studentNumber = number; } public int getStudentNumber(){ return studentNumber; } } よろしくおねがいします。

    • ベストアンサー
    • Java
  • テンプレートクラスとSTLを利用したMyListクラス

    こんにちは。STLのリストを使い自分だけのMyListクラスを作ろうとしたのですが、コンパイルできません。 エラーメッセージは警告 std::list<T>::iterator' : 依存名は型ではありません。 とでます。 ご教授お願いします。 #include<list> #include<iterator> template <class T> class CMyList { public: CMyList(); //virtual ~CMyList(); //bool HasNext(); //T Next(); //void Pushback( T t ); //void EraseCheck(); //T GetFirst(); private: std::list< T > m_List; std::list< T >::iterator m_It;//コンパイルエラー }; template <class T> CMyList<T>::CMyList() { m_List.clear(); std::list< T > ::iterator it = m_List.begin();//こう宣言する分にはOK m_It = m_List.begin(); } int main() { CMyList<int> m_List; return 0; }

  • enum型

    お世話になります。 Javaのenum型に関してお聞きしたいです。 JavaのAPIドキュメントを見ると、enumのvalueOfメソッドに関して、 以下のように記述がありますが、具体的にどのように使用するので しょうか? public static <T extends Enum<T>> T      valueOf(Class<T> enumType,String name) どうかよろしくお願いします。

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

    次のようなプログラムを書きました。 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
  • 継承について

    以下のような問題(SJC-P試験)があり、 解説では考え方として ●メンバがフィールドなら「変数の型」 ●インスタンスメソッドなら「実際のオブジェクトの型」 ●クラスメソッドなら「変数の型」 とありました。 できればなぜこのような考え方(法則)になるか理解したいと思っています。 #当方、Javaプログラミング経験ゼロで、実際に下記のようなコーディングをするかどうかもわかりませんが、 #丸暗記だと実際のコーディングで使えそうにないので、できれば理解したいと思ってます。 下記問題は解説の考え方さえ丸暗記すれば解けるのかもしれませんが (なぜ解説のような考え方になるのか含め)教えていただけませんでしょうか。 ----- 【問題1】 class Super{  int d = 10;  void meth()System.out.println(d); } class Sub extends Super{  double d = 20.0;  void meth()System.out.println(d); } class Sample1{  public static void main(String[] args){  Super s = new Sub();  System.out.println(s.d);  s.meth(); } 【答え】 10 20.0 ----- 【問題2】 class Super{  static int d = 10;  static void meth()System.out.println(d); } class Sub extends Super{  static double d = 20.0;  static void meth()System.out.println(d); } class Sample2{  public static void main(String[] args){  Super s = new Sub();  System.out.println(s.d);  s.meth(); } 【答え】 10 10 ----- よろしくお願い致します。

    • ベストアンサー
    • Java
  • デッドロックに関して1

    下記のサンプルソースは、デッドロックを起こすソース なのですが、 public class Deadlock extends Thread { public static Object l1 = new Object(); public static Object l2 = new Object(); private int index; public static void main(String[] a) { Thread t1 = new ThreadA(); Thread t2 = new ThreadB(); t1.start(); t2.start(); } private static class ThreadA extends Thread { public void run() { synchronized (l1) { System.out.println("スレッド1: l1に対するロックを取得"); try { Thread.sleep(10); } catch (InterruptedException e) {} System.out.println("スレッド1: l2のロックの開放待ち"); synchronized (l2) { System.out.println("スレッド1: l1、l2に対するロックを取得"); } } } } private static class ThreadB extends Thread { 文字数オーばーのため削除 } これを参考に、Junitでデッドロックを起こすサンプルを作りたいです。 MultithreadedTestCaseと ControllableTestThreadを使い サンプルを作りたいのですが、 英語が良くわからず苦戦しております。 なにか、よいアドバイスをいただけませんでしょうか? よろしくお願いします

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

    行列式についての問題です。б=(上段が12345下段が14325)の2と4の互換はわかるのですが、なぜб=(2 4)なのですか?(4 2)ではダメなのですか?あと2つの違いは何なのですか?解説お願いします(T-T)