2015-05-04 15 views
6

Sto codificando in IntelliJ IDEA. Durante il debug della mia applicazione, non posso utilizzare alcune implementazioni del metodo predefinito in Orologi.Il debugger Java non può chiamare alcune implementazioni del metodo predefinito

Ecco un esempio condensata:

public class Friendship { 
    interface Friend { 
     default void sayHiTo(Friend friend) { 
      System.out.println("Hi, " + friend.hashCode()); 
     } 

     default int amountOfHands() { 
      return 2; 
     } 
    } 

    public static class BasicFriend implements Friend { 

     int numberOfFaces() { 
      return 1; 
     } 
    } 

    public static void main(String[] args) { 
     System.out.println("Put a breakpoint here"); 
    } 
} 

In main() metodo ho messo un punto di interruzione e impostare tre orologi:

// Default interface method with dependency 
new BasicFriend().sayHiTo(new BasicFriend()) 

// Default interface method without dependency 
new BasicFriend().amountOfHands() 

// Class method 
new BasicFriend().numberOfFaces() 

Il primo orologio tiri NoSuchMethodException lamentando che il metodo Friendship$BasicFriend.sayHiTo() non esiste .

Il secondo orologio funziona correttamente, ma stranamente riporta un oggetto in scatola {[email protected]} "2" anziché solo un primitivo 2.

Il terzo orologio riporta un primitivo 1, proprio come previsto.

Perché il primo orologio non funziona? è un insetto? Questo è effettivamente collegato all'IDE? È a causa di qualche difetto concettuale dei metodi predefiniti? Dovrebbe funzionare come lo voglio in primo luogo? Lo strano risultato del secondo orologio è in qualche modo collegato al problema nel primo orologio?

+2

Dopo aver riletto la tua domanda, ottengo la stessa eccezione per il tuo primo orologio. Nel tuo primo orologio ricevo 'java.lang.ClassCastException: com.sun.tools.jdi.InterfaceTypeImpl non può essere lanciato su com.sun.tools.jdi.ClassTypeImpl'. Sto indovinando che questo è solo un bug del compilatore IntelliJ. Sto usando IntelliJ 14.1.2 su Ubuntu. – mkobit

risposta

6

Prima di JDK 8u40, i metodi di interfaccia statici e predefiniti non erano supportati da JDI (Java Debugger Interface), JDWP (Java Debugger Wire Protocol) e JDB (il debugger Java standard). Questo è bug JDK-8042123, che viene registrato come fisso in 8u40 e un blurb corrispondente appare nello 8u40 release notes.

Aggiornamento a 8u40 o successivo per risolvere questo problema, almeno sul lato JDK.

Dalla descrizione del bug, sembra che siano necessarie anche modifiche al lato del debugger, per evitare di lanciare gli oggetti com.sun.jdi.InterfaceType su com.sun.jdi.ClassType, ma chiamare direttamente InterfaceType.invokeMethod().

Nel caso specifico di IntelliJ, Suseika confirmed in a comment che 14.1.2 ha risolto il problema principalmente (tranne il pugilato imprevisto), anche se Mike Kobit still experiences this problem su quella versione con un ClassCastException indicativo del cast errato sopra.

+0

Ho installato Java 8u45, ma ho ancora ottenuto NoSuchMethodException. Tuttavia, l'aggiornamento di IntelliJ IDEA da 14.0.3 a 14.1.2 ha fatto il trucco: ora i metodi predefiniti nel debugger funzionano quasi correttamente (il secondo ancora restituisce oggetti in scatola, ma questo è per un'altra domanda). – gvlasov

+2

@Suseika Grazie per l'informazione (modificata nella risposta). Ciò sembra confermare che sono richieste modifiche al debugger. –

+0

Informazioni sulla boxe. Ho presentato una segnalazione di bug al riguardo, puoi trovarla qui: https://youtrack.jetbrains.com/issue/IDEA-139945 – gvlasov