2010-11-10 16 views
6

Abbiamo una gerarchia di classi simile a questo:Sun JDK 1.5 non può errore dereferenzia con i generici

public class TestDereference { 
private static MainInterface mi = new MainInterfaceImpl(); 

public static void main(String[] args) { 
    System.out.println(mi.getSubInterface().getField()); 
} 
} 

interface MainInterface { 
<T extends SubInterface> T getSubInterface(); 
} 

interface SubInterface { 
Field getField(); 
} 

class Field { 
@Override 
public String toString() { 
    return "Hooray!"; 
} 
} 

class SubInterfaceImpl implements SubInterface { 
Field f = new Field(); 

public Field getField() { 
    return f; 
} 

} 

class MainInterfaceImpl implements MainInterface { 
SubInterfaceImpl si = new SubInterfaceImpl(); 

public <T extends SubInterface> T getSubInterface() { 
    return (T) si; 
} 
} 

Le interfacce sono in realtà più di un'implementazione, ma non è questo il problema. Compilare questo con il compilatore Eclipse o Java 1.6 funziona bene (come visto su ideone). Ma se provo a compilare questo con Java 1.5 (che è uno dei requisiti del nostro progetto) dà il seguente errore:

TestDereference.java:12: test.SubInterface cannot be dereferenced 
       System.out.println(mi.getSubInterface().getField()); 
                ^

Si noti inoltre che non accade con JDK 1.6 utilizzando -target 1.5 sia, solo con JDK 1.5

Gli unici casi in cui si verifica questo errore che ho trovato sul web sono legati a fare le cose in questo modo:

double d = 2.0; 
d.toString(); 

dove è evidente quale sia il problema.

Ma nel mio caso dovrebbe funzionare, poiché è chiaro che getSubInterface() restituisce una classe di implementazione SubInterface che dispone del metodo getField().

Quindi questo è un bug del compilatore? E quali opzioni ho oltre a fare mi.<SubInterface>getSubInterface() ogni volta (che funziona, ma dal momento che Eclipse non lo segnala come un errore, la maggior parte delle persone nel team dimentica di farlo, e la maggior parte di loro usa solo JDK 1.6 così non lo fanno notalo anche quando compili con maven/cmd line)?

+0

Quali versioni del JDK esatto stai usando? (5 e 6?) –

+0

1.5.0_22 e 1.6.0_20 (in base a 'javac -version') –

+0

Cosa succede quando si tenta il flag del compilatore' -source 1.5' o se si imposta il livello di conformità del compilatore Eclipse su 1.5 invece di 1.6? –

risposta

1

controllo bug: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5003431

Opzione uno:

SubInterface si = mi.getSubInterface(); 
si.getField(); 

Opzione due:

mi.<SubInterface>getSubInterface().getField() 
+0

Quindi penso che se sono bloccato con 1.5 non c'è molto che posso fare a parte queste due opzioni. Speravo in qualcosa di un po 'più elegante, suppongo, ma questo dovrà fare. –

+0

Ho accettato la tua risposta per aver anche fornito il link al bug report, che mostrava che era stato corretto solo in 1.6 –

1

Immagino che questo sia un bug corretto in Java6.

Riscrivere il principale metodo renderà le cose funzionano sia Java5 e 6 come segue:

public static void main(String[] args) { 
    SubInterface subInterface = mi.getSubInterface(); 
    System.out.println(subInterface.getField()); 
} 

Sembra Java5 ha bisogno il compito di ricavare correttamente il tipo T, anche se è già dichiarata si estende SubInterface. Java6 gestisce questo correttamente e non ha bisogno del compito aggiuntivo.

Problemi correlati