2015-09-09 22 views
7

Si consideri l'esempio seguente,metodo di classe Super e interfaccia metodo predefinito di risoluzione dei conflitti

public class Testing extends SupCls implements Intf { 
    public static void main(String[] args) { 
     new Testing().test(); 
    } 
} 

class SupCls { 
    public void test() { 
     System.out.println("From SupCls"); 
    } 
} 

interface Intf { 
    public default void test() { 
     System.out.println("From Intf"); 
    } 
} 

Come si può vedere, non c'è alcuna connessione tra SupCls classe ed Intf interfaccia. Ma entrambi sono che definiscono un metodo comune.

E la classe Testing si estende SupCls e in esecuzione Intf.

Così, quando chiamo test() metodo su Testing l'uscita è,

From SupCls 

Che credo abbia senso, perché si estende da una classe deve avere la priorità maggiore di attuazione da un'interfaccia.

Tuttavia, l'eclissi segnala altrimenti, come mostrato nella schermata di acquisizione sottostante.

Screen Capture of Eclipse

Credo fermamente che questo è un bug in Eclipse.

Ma prima di assumere, questo comportamento è definito & documentato nel JLS? O c'è qualcos'altro che definisce questo comportamento?

Modifica: la versione di Eclipse è Mars Release (4.5.0), se è importante.

+2

Dovrebbe essere un bug in eclissi. I metodi predefiniti fanno parte di Java8 e questo scenario non avrebbe avuto senso per JDK 7 o versioni precedenti. –

+0

Il comportamento predefinito di eclissi. Mostra il metodo dell'interfaccia invece del metodo super-classe. In Even below java 1.8 Mostra i metodi dell'interfaccia (anche se non è un metodo predefinito) –

+4

Controlla la regola n. 1 riguardante il metodo predefinito [Posta da Brian Goetz] (http://mail.openjdk.java.net/pipermail/lambda-dev/ 2013-marzo/008435.html) –

risposta

4

La tua ipotesi è giusto, il metodo concreto ereditato dalla superclasse ha la precedenza rispetto al metodo default dal interface:

JLS §8.4.8. Inheritance, Overriding, and Hiding

Una classe Ceredita dalla sua superclasse diretta e superinterfaccia diretta tutti abstract e predefinita (§9.4) i metodi m per il quale tutte le seguenti condizioni:

...

  • Nessun metodo dichiarato in C ha una firma che è una subsignature (§8.4.2) della firma della m.
  • Nessun metodo concreto ereditato da C dalla sua superclasse diretta dispone di una firma che è una sottoscala della firma di m.

Il secondo proiettile citato si applica qui, c'è un metodo concreto ereditato dalla superclasse diretto con una firma del caso, in modo che il metodo di default non è ereditaria.

La documentazione cancella anche ogni dubbio con una nota aggiuntiva:

Si noti che è possibile per un metodo concreto per prevenire ereditato l'eredità di un metodo astratto o di default. (Più tardi ci sarà affermare che il metodo concreto esegue l'override del metodo astratto o di default "da C".)

quindi è come SupCls.test() override Intf.test() quando si tratta di classe Testing.

In altre parole, hai ragione, si tratta di un bug in Eclipse, ma fintanto che riguarda solo il modo in cui la proposta è reso, lo considererei un minore bug. La sorgente inserita sarà la stessa, indipendentemente dal fatto che nella proposta sia stato eseguito il rendering di D oppure no.

1

Sembra che la versione di Eclipse sia importante!

In Eclipse Luna (4.4.1) i punti di riferimento per SupCls invece di Intf

enter image description here

probabilmente di un bug in Eclipse Marte

5

Questo certamente è un bug in Eclipse, ma nel codice proposte di completamento piuttosto che nel compilatore. Passando il mouse sopra la chiamata per testare o Open Declaration, si passa al metodo SupCls e l'esecuzione del codice stampa correttamente "Da SupCls" che lo dimostra. Si prega di inviare un bug contro JDT ui per le indagini

Problemi correlati