2012-04-04 11 views
5

Sto leggendo "disegno API pratico" e trovare paragrafo seguente:.Utilizzo di getter/setter diversi da quelli pubblici per la compatibilità binaria?

"L'altro motivo per preferire metodi più campi si trovano nella specifica JVM sei permesso di passare un metodo da una classe a uno delle sue superclassi e mantengono ancora la compatibilità binaria.Così, un metodo inizialmente introdotto come Dimension javax.swing.JComponent. getPreferredSize (Dimensione d) può essere eliminato in una nuova versione e spostato in Dimensione java.awt.Component.getPreferredSize (Dimensione d) , poiché JComponent è una sottoclasse di Component. Una modifica come questa è realmente avvenuta in JDK 1.2 e ciò potrebbe essere fatto solo perché il campo è stato incapsulato da un metodo. Un'operazione come questa non è consentita per i campi. è definito in una classe, deve stare lì per sempre r per mantenere la compatibilità binaria, che è un'altra ragione per mantenere privati ​​i campi "

poiché sono d'accordo che usare getter/setter è il modo migliore. Ma non capisco perché lo spostamento del campo pubblico verso la classe genitore possa rompere la compatibilità binaria? Dovresti comunque essere in grado di accedere a quel campo attraverso la classe figlio purché sia ​​pubblico in genitore.

risposta

3

Una volta che un campo è definito in una classe, deve rimanere lì per sempre per mantenere la compatibilità binaria

che sarebbe molto sorprendente:

Il linguaggio Java Specification, Java SE 7 Edition , defines il nome binario di un'espressione di accesso di campo non qualificato come segue:

Data un'espressione legale che indica un accesso di campo in una classe C, fa riferimento a un campo non costante (§13.4.9) nome f dichiarata in un (possibilmente distinti) classe o interfaccia D, definiamo il tipo qualificante del riferimento campo come segue:

  • Se il espressione è della forma Primary.f poi:
    • Se il tipo di fase di compilazione primario è un tipo di intersezione (§4.9) V1 & ... & Vn, quindi il tipo di qualifica del riferimento è V1.
    • In caso contrario, il tipo di tempo di compilazione di Primary è il tipo di riferimento del riferimento.

(le specifiche del linguaggio per Java 1.5 uses lo stesso testo)

In altre parole, il nome binario di un'espressione di accesso al campo non fa riferimento al tipo che dichiara il campo, ma solo al tipo dell'espressione primaria che usiamo per accedere a quel campo, quindi qualsiasi la superclasse di quel tipo dichiara il campo, il compilatore è richiesto per emettere lo stesso riferimento di campo nel file di classe.

Infatti, quando provai poc'anzi evolvere da

package p; 

public class Super { 

} 

package p; 

public class Sub extends Super { 
    public String message; 

    @Override 
    public String toString() { 
     return message; 
    } 
} 

a

package p; 

public class Super { 
    public String message; 
} 

package p; 

public class Sub extends Super { 
    @Override 
    public String toString() { 
     return message; 
    } 
} 

ricompilandosi

package p; 

public class Main { 
    public static void main(String[] args) { 
     Sub sub = new Sub(); 
     sub.message = "hello"; 
     System.out.println(sub); 
     System.out.println(sub.message); 
    } 
} 

ho ancora ricevuto l'uscita del

hello 
hello 

, non un LinkageError.

Per concludere, tale affermazione non è vera per Java 7. Potrebbe essere stato vero per JDK 1.4 o precedente, che è stato dichiarato a fine vita più di 5 anni fa. Ad ogni modo, forse dovresti usare un libro migliore/più recente?

+0

Questa è solo una cosa che posso indovinare. Forse ai vecchi tempi, lo è. –

0

Se ricordo correttamente, il libro lo spiega, ma attualmente non ne ho a disposizione. Penso che si trattasse di sottili differenze tra il linguaggio Java e il formato del file di classe (che viene utilizzato anche da altri linguaggi oltre a Java).

Controllare il libro un po 'prima o dopo. Chiedi se hai altre domande su quella parte.

+0

In realtà posto la domanda dopo aver terminato quel capitolo. Non ho visto alcuna spiegazione. Anche se ci sono alcune cose che parlano dell'Hotspot JVM, non penso che la parte risponda alla mia domanda –