2016-08-10 4 views
1

Meine IDE beschwert, dass „NCM_Callable nicht zu Callable<ReturnInterface<? extends Object>> auf dieser Linie this.ph.submitCallable(new NCM_Callable(this, new DeviceGroup(this.deviceGroupNames.get(i)), ph)); In the "fetchDevices()" method Java Generics Probleme verursacht

Ich möchte umgewandelt werden nur in der Lage sein Callables meiner ecs zu übergeben, die eine ReturnInterface jede Art von Objekt enthält, zurückgibt.

ich vermute, etwas falsch mit meiner Nutzung von <> allgemeinen Definitionen gibt es, aber ich kann nicht scheinen, um herauszufinden, was es ist. Jede mögliche Hilfe würde geschätzt.

@Override 
public void fetchDevices() throws Exception { 
    System.out.println("[NCM_Fetcher]fetchingDevices()"); 
    for (int i = 0; i < this.deviceGroupNames.size(); i++) { 
     System.out.println("[NCM_Fetcher]fetchingDevices().submitting DeviceGroup Callable " + i+ " of "+this.deviceGroupNames.size()); 
     this.ph.submitCallable(new NCM_Callable(this, new DeviceGroup(this.deviceGroupNames.get(i)), ph)); 
    } 
    this.ph.execute();//See progressBarhelper below 
} 

ProgressB arHelper: Ich habe einen seltsamen Fehler bei "ecs.submit()". Nach dem, was ich gelesen habe, scheint es, dass ich eine Hilfsmethode brauche? Wie repariere ich?

public class ProgressBarHelper extends SwingWorker<Void, ReturnInterface> implements ActionListener { 
ExecutorService pool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); 

protected CompletionService<ReturnInterface<?>> ecs; 

public final void submitCallable(Callable<? extends ReturnInterface<?>> c) { 
    //create a map for this future 
    ecs.submit(c); 
    this.callables.add(c);//Error here is Callable<CAP#1 cannot be converted to Callable<ReturnInterface<?>> 
    System.out.println("[ProgressBarHelper]submitted"); 

} 
} 

Und schließlich die Klasse NCM_Callable mit ihren Generics.

public class NCM_Callable implements Callable<ReturnInterface<ResultSet>>, ReturnInterface<ResultSet> { 
+0

Zuerst erstellen [MCVE]. Sie werden wahrscheinlich Ihr Problem dabei lösen. – 4castle

+0

Mögliches Duplikat von [Java Generics, verschachtelte Sammlung von Platzhaltern] (http://stackoverflow.com/questions/6293871/java-generics-nested-collection-of-wildcard) – 4castle

+0

Es ist kein Duplikat. –

Antwort

0

Soweit ich überprüfen konnte, die problematische Zeile ist ecs.submit:

public final void submitCallable(Callable<? extends ReturnInterface<?>> c) { 
    // create a map for this future 
    ecs.submit(c); // Error here is Callable<CAP#1 cannot be converted to Callable<ReturnInterface<?>> 
    this.callables.add(c); // this is fine on my machine 
} 

Das Problem ist, dass Java Generika invariant ist. Es gibt eine Abhilfe für dieses: Sie den Platzhalter mit dem Namen ersetzen kann, gebunden Typ:

public final <T extends ReturnInterface<?>> void // this is how you name and bind the type 
    submitCallable(Callable<T> c) { // here you are referring to it 
    // create a map for this future 
    ecs.submit((Callable<ReturnInterface<?>>) c); // here you need to cast. 
    ... 
} 

Das Casting in Laufzeit aufgrund type erasure in Ordnung ist. Aber dann sei sehr vorsichtig bei dem was du mit diesen Callables machst.

Schließlich ist dies, wie Sie diese Funktion aufrufen kann:

private static class ReturnInterfaceImpl implements ReturnInterface<String> { 

}; 

public void foo() { 
    Callable<ReturnInterfaceImpl> c = new Callable<ReturnInterfaceImpl>() { 
     @Override 
     public ReturnInterfaceImpl call() throws Exception { 
      return null; 
     } 
    }; 
    submitCallable(c); 
} 
+0

Ich war verblüfft und nur am Ende akzeptiert eine aufrufbar. Es ist gut, dass jemand erklären konnte, warum mein Code nicht funktionierte. –