2017-04-17 30 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

「如何創建一個可以訪問類實例變量的泛型,並且它是自己的實例變量?」你不能。泛型只會讓您訪問已擦除類型的成員變量 - 在這種情況下,「對象」沒有公共字段。 –

+0

如何在通用文件中聲明一個名稱實例變量?我會怎樣解決這個問題? –

回答

0

您無法使用泛型訪問不相關類的成員變量。使用概念

Java泛型的工作稱爲類型擦除。這基本上意味着在編譯代碼時,編譯器將刪除所有泛型,並且使用類型變量的已擦除類型留下「非泛型」代碼。

在你class files<T>的情況下,的T擦除類型是ObjectTT extends 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); 

    } 

} 

希望這有助於:)

+0

如果我將方法添加到Thing類中,它應該工作? –

+0

如果你的意思是靜態然後否,因爲如果你想要它作爲一個靜態方法,你將不得不有兩個文件對象作爲參數,而不是一個 ,如果你的意思是直接添加它沒有靜態,那麼是的,但你不需要泛型了。 –

+0

感謝您的幫助。 –

0

您試圖訪問一個變量(name)這不是files<T>類的成員。

既然你正試圖來比較(不)平等傳遞的類型的名稱,你需要確保類型傳遞的。

在你的情況,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)); 

    } 

} 
相關問題