2017-04-17 12 views
-1

私はJavaとジェネリックのトピックを学習しています。ワイルドカードの概念を理解するために、私は次のコードを使いこなしています。私はジェネリッククラスを取り、それを別のジェネリッククラスの型の名前と比較するメソッドを作成しようとしています。名前が解決できないと私に伝えています。クラスインスタンス変数にアクセスできるジェネリックを作成する方法、また自分自身のインスタンス変数を作成する方法次のコードで何が問題になりますか?ワイルドカードとして使用するオブジェクトの変数を取得する方法

package wildcardExample; 

class tape{ 
    String name; 
    int ItemNum; 
} 
class paper{ 
    String name; 
    int itemNum; 
} 
class cds{ 
    String name; 
    int itemNum; 
} 

class files<T>{ 
    T myobject; 

    files(T inobject){ 
    myobject = inobject; 
} 

T returnname(){ 
    return myobject; 
} 

static void compareName(files<?> infiles){ 
    if(this.name == infiles.name){ 
     System.out.println("name is the same" + this.name); 
    } 
} 
} 
public class myWildcard { 
    public static void main(String args[]){ 

    tape MyTape = new tape(); 
    MyTape.name = "hello world"; 

    paper MyPaper = new paper(); 
    MyPaper.name = "hello world"; 


    files<tape> MyFiles1 = new files<tape>(MyTape); 
    files<paper> MyFiles2 = new files<paper>(MyPaper); 

    MyFiles1.compareName(MyFiles2); 

    } 

    } 
+0

やりたいように見える、あなたの 'files'をクラスは' name'のインスタンス変数を定義していません。 'this.name'も' infiles.name'も意味をなさない。 – user2357112

+0

「クラスインスタンス変数にアクセスできるジェネリックを作成する方法と、自己のインスタンス変数を作成する方法」できません。ジェネリックスは、消去された型のメンバ変数へのアクセス権しか与えません。この場合、 'Object'にはパブリックフィールドがありません。 –

+0

ファイル内に名前インスタンス変数を宣言するにはどうすればよいですか?このコードを修正するにはどうすればよいですか? –

答えて

0

無関係なクラスのメンバー変数にはジェネリックでアクセスできません。

型消去という概念を使用してJavaジェネリックが動作します。これは基本的に、コードがコンパイルされると、ジェネリックのすべてがコンパイラによって削除され、タイプ変数の消去された型を使用して「非汎用」コードが残されることを意味します。あなたのclass files<T>の場合

Tの消去タイプは(TT extends Objectの省略形です)Objectです。したがって、コードではメンバー変数とメソッドにしかアクセスできませんObjectからです。しかしObjectには、一般に公開されているメンバ変数がないため、汎用変数のメンバ変数にはアクセスできません。

ここで正しいアプローチは、あなたのタイプのそれぞれは、いくつかのインターフェイスを実装することです。その後、

interface SomeInterface { 
    String name(); 
    int itemNum(); 
} 

class tape implements SomeInterface { 
    String name; 
    int ItemNum; 

    @Override public String name() { return name; } 
    @Override public int itemNum() { return ItemNum; } 
} 

// etc. 

とあなたのジェネリックの上限としてSomeInterfaceを使用します。

class files<T extends SomeInterface> 

今、あなたはname()を呼び出すことができますitemNum()myobjectに設定します。

0

次のようなものが欲しいと思いますか?

package wildcardExample; 

class Thing { 
    String name; 
    int ItemNum; 
} 
class Tape extends Thing { } 
class Paper extends Thing { } 
class CDs extends Thing { } 

class Files<T extends Thing>{ 
    T myobject; // this way you will ensure that myobject has name field since it instance of type Thing (or any subclass of Thing) 
    Files(T inobject){ 
     myobject = inobject; 
    } 

    T returnName(){ 
     return myobject; 
    } 

    void compareName(Files<?> infiles){ 
     // you cannot use this in a static method since this method doesn't belong to the object but to the class 
     if(this.name == infiles.name){ 
      System.out.println("name is the same" + this.name); 
     } 
    } 
} 
public class MyWildcard { 
    public static void main(String args[]){ 

     Tape MyTape = new Tape(); 
     MyTape.name = "hello world"; 

     Paper MyPaper = new Paper(); 
     MyPaper.name = "hello world"; 


     Files<Tape> MyFiles1 = new Files<Tape>(MyTape); 
     Files<Paper> MyFiles2 = new Files<Paper>(MyPaper); 

     MyFiles1.compareName(MyFiles2); 

    } 

} 

希望はこのことができます:)あなたはfiles<T>クラスのメンバーではない変数(name)にアクセスしようとしている

+0

メソッドをThingクラスに追加するとうまくいくはずですか? –

+0

静的な場合は、静的メソッドとして使用する場合は、 の代わりに2つのファイルオブジェクトを1つのパラメータとして持つ必要があります。静的ではなく直接追加することを意味しますが、ジェネリックは必要ありませんもう –

+0

ご協力いただきありがとうございます。 –

0

for(等)で渡された型の名前を比較しようとしているので、渡される型が確実である必要があります。

あなたのケースでは、Tは何でもかまいません。タイプ/オブジェクトがわからないため、メンバーを呼び出すことはできません。クラス/インタフェースが上限を定義するところ

はあなたが何ができるか、つまり、あなたが探しているメンバーを持つことが保証されているものにバウンドTに上限と呼ばれている

files<T extends {class/interface}>です/これにより、あなたが探しているメンバーが含まれていることを保証します。示すように

あなたはそれが意図したとおり、これを実証し、振る舞いコードは次のとおりです。コードの規則に続いて

public class Temp { 

    public static void main(String[] args) { 
     Paper paper = new Paper(); 
     paper.setName("name"); 

     Tape tape = new Tape(); 
     tape.setName("name"); 

     Generic<Paper> gen1 = new Generic(paper); 
     Generic<Tape> gen2 = new Generic(tape); 

     System.out.println(gen1.compare(gen2)); 
    } 
} 

interface Tester { 
    void setName(String name); 

    String getName(); 
} 

class Paper implements Tester { 
    String name; 

    @Override 
    public void setName(String name) { 
     this.name = name; 
    } 

    @Override 
    public String getName() { 
     return name; 
    } 
} 

class Tape implements Tester { 
    String name; 

    @Override 
    public void setName(String name) { 
     this.name = name; 
    } 

    @Override 
    public String getName() { 
     return name; 
    } 
} 

// The extends keyword is used to indicate an upper bound 
// which refers to any class that extends/implements Tester 
// is a valid type argument to the Generic class. 
// It helps to use the methods that Tester declares 

class Generic<T extends Tester> { 
    T type; 

    Generic(T type) { 
     this.type = type; 
    } 

    boolean compare(Generic<? extends Tester> generic) { 
     return this.type.getName().equals(generic.type.getName()); 
    } 
} 

は良い習慣です。

はそれが役に立てば幸い:)

0

これは他の問題の中で、私は

package wildcardExample; 

class Thing { 
    String name; 
    int ItemNum; 

    boolean comparethings(Thing mything){ 
     if(this.name == mything.name){ 
      return true; 
     }else{ 
      return false; 
     } 

    } 
} 
class Tape extends Thing { } 
class Paper extends Thing { } 
class CDs extends Thing { } 

class Files<T extends Thing>{ 
    T myobject; // this way you will ensure that myobject has name field since it instance of type Thing (or any subclass of Thing) 
    Files(T inobject){ 
     myobject = inobject; 
    } 

    T returnName(){ 
     return myobject; 
    } 

    boolean compareName(Files<?> infiles){ 
     // you cannot use this in a static method since this method doesn't belong to the object but to the class 
     boolean myboo = myobject.comparethings(infiles.myobject); 
     return myboo; 
    } 
} 
public class myWildcard { 
    public static void main(String args[]){ 

     Tape MyTape = new Tape(); 
     MyTape.name = "hello world"; 

     Paper MyPaper = new Paper(); 
     MyPaper.name = "hello world"; 


     Files<Tape> MyFiles1 = new Files<Tape>(MyTape); 
     Files<Paper> MyFiles2 = new Files<Paper>(MyPaper); 

     System.out.println(MyFiles1.compareName(MyFiles2)); 

    } 

} 
関連する問題