2016-07-19 13 views
0

Betrachten Sie das folgende Beispiel:Was ist das Konzept hinter CAP # 1 in generischer JACA (Wildcard)?

class First<T > 
{ 
    T s; 
    First(T s) 
    { 
     this.s=s; 
    } 
    void setS(T s) 
    { 
     this.s=s; 
    } 
    void getS() 
    { 
    System.out.println(s); 
    } 
} 

class Use 
{ 
     public static void setFirst(First<?>f) 
     { 
       f.setS(7); 
     } 
     public static void main(String[] args) 
     { 
       First <Integer> f4 = new First<Integer>(5); 
       f4.getS(); 
       setFirst(f4);     
     } 
} 

Ich weiß, dass Compiler einen Fehler geben, weil bestimmte Schreiboperationen in einem Verfahren nicht erlaubt, deren formale Parameter für Generika Wild-Card verwendet. Compiler-Fehler ist:

[email protected]:~/codes/java/generics$ javac -Xdiags:verbose *.java 
Use.java:5: error: method setS in class First<T> cannot be applied to given types; 
     f.setS(7); 
     ^
    required: CAP#1 
    found: int 
    reason: argument mismatch; int cannot be converted to CAP#1 
    where T is a type-variable: 
    T extends Object declared in class First 
    where CAP#1 is a fresh type-variable: 
    CAP#1 extends Object from capture of ? 
1 error 
[email protected]:~/codes/java/generics$ 

Es sieht aus wie CAP # 1 ist ein Datentyp. Ich weiß nichts über dieses Konzept. Bitte helfen Sie.

+5

See [* Wildcard Capture and Helper-Methoden *] (https: // docs.oracle.com/javase/tutorial/java/generics/capture.html). – trashgod

Antwort

0

In Generika wird alles nur zur Kompilierzeit ersetzt, um Typ Sicherheit zu liefern. In Ihrem Beispiel verarbeitet der Compiler den f Eingabeparameter als vom Typ Object. Wenn die Methode setFirst(First<?>f)f.setS(7); aufruft, kann der Compiler den Objekttyp, in den initialisiert wird, nicht bestätigen und es wird ein Fehler erzeugt.

Wenn dieser Fehlertyp auftritt, bedeutet dies normalerweise, dass der Compiler glaubt, dass Sie einer Variablen den falschen Typ zuweisen. Generics wurden der Java-Sprache hinzugefügt, um die Typsicherheit zur Kompilierzeit zu erzwingen.

public static void setFirst(First<?>f) // at compile time no special type parameter found. So No Replacement will take place. 
     { 
       f.setS(7); //confusing case because it not a type Parameter should be replace with any Java Class not the Constant. 
     } 

Aber hier in anderen Fällen, in Haupt

First <Integer> f4 = new First<Integer>(5); // T is replaced with Integer. 
f4.getS(); // It will produce 5 
setFirst(f4); // it will also get executed because of f4 is a object of First<Integer>. 
0

Das hier Problem ist, dass <?>List<?> bedeutet Liste der unbekannten Art so kann nichts hinzugefügt werden, um es außer null als Compiler unbekannter Typ dh darstellen kann‘ t Überprüfen Sie den Typ beim Hinzufügen.

Sie können jedoch den Parametertyp <? super Integer>-<Integer> oder ändern diese Methode funktioniert:

public static void setFirst(First<Integer> f) { 
    f.setS(7); 
} 

Siehe: wildcards in generics