Perché tutti i campi in un'interfaccia sono implicitamente statici e finali?


100

Sto solo cercando di capire perché tutti i campi definiti in un'interfaccia sono implicitamente statice final. L'idea di mantenere i campi staticha senso per me dato che non puoi avere oggetti di un'interfaccia ma perché lo sono final(implicitamente)?

Qualcuno sa perché i progettisti Java sono andati a creare i campi in un'interfaccia statice final?


Per una nota per me: è statico perché i campi dell'interfaccia non diventeranno una parte dell'oggetto che lo implementa.
Piove il

Risposte:


126

Un'interfaccia non può avere un comportamento o uno stato perché ha lo scopo di specificare solo un contratto di interazione, nessun dettaglio di implementazione. "Nessun comportamento" viene applicato non consentendo i corpi di metodo / costruttore o blocchi di inizializzazione statici / istanza. "Nessuno stato" viene applicato consentendo solo i campi finali statici. Pertanto, la classe può avere uno stato (stato statico), ma lo stato dell'istanza non viene dedotto dall'interfaccia.

BTW: una costante in Java è definita da un campo finale statico (e per convenzione il nome utilizza UPPER_CASE_AND_UNDERSCORES).


54
Non è necessariamente vero che i campi finali siano costanti; è garantito solo per i tipi primitivi. In generale, la parola chiave finale significa semplicemente che la posizione di memoria non cambierà.
Pop il

8
Non ho detto che i campi finali sono costanti, solo che le costanti sono campi finali. Si noti che è consentito inserire un campo finale statico non primitivo in un'interfaccia. Anche se il contenuto di quel campo potrebbe cambiare, il riferimento ad esso è costante.
Adriaan Koster

1
@AdriaanKoster Hai detto esattamente che il campo finale è costante: Nessuno stato viene applicato solo consentendo le costanti. - questa frase implica che tutti i campi finali siano costanti. Potresti provare a discutere ulteriormente sulle parole che hai usato, ma ovviamente la tua affermazione è fuorviante.
Tomáš Zato - Ripristina Monica il

2
Deve essere il mio intelletto in declino, ma dopo sei anni a guardare questa risposta, che sembra essere la mia risposta con il punteggio più alto, ancora non capisco le osservazioni. Si prega di suggerire una formulazione diversa perché non vedo nulla di sbagliato.
Adriaan Koster

Potrebbe essere stata l'intenzione dei progettisti java di rendere un'interfaccia senza stato, ma hanno fallito perché un campo di istanza può essere una classe modificabile. Invece di ammettere che hanno fallito, scelgono di forzare i campi di istanza a static final, che è il più vicino al reale (vero essendo C / C ++) constcome puoi ottenere in java. Sfortunatamente questo è implicito e può creare confusione per i non esperti. (Mi sono appena reso conto che lo sono staticperché ho osservato un comportamento non intenzionale. Ho imparato che sono finalsolo da questa risposta.)
not-a-user

27

Motivo dell'essere final

Qualsiasi implementazione può modificare il valore dei campi se non sono definiti come finali. Quindi diventerebbero parte dell'implementazione. Un'interfaccia è una specifica pura senza alcuna implementazione.

Motivo dell'essere static

Se sono statici, appartengono all'interfaccia e non all'oggetto, né al tipo di runtime dell'oggetto.


18

Ci sono un paio di punti sorvolati qui:

Solo perché i campi in un'interfaccia sono implicitamente statici finali non significa che debbano essere costanti in fase di compilazione, o addirittura immutabili. Puoi definire ad es

interface I {
  String TOKEN = SomeOtherClass.heavyComputation();
  JButton BAD_IDEA = new JButton("hello");
}

(Attenzione che farlo all'interno di una definizione di annotazione può confondere javac , in relazione al fatto che quanto sopra viene effettivamente compilato in un inizializzatore statico.)

Inoltre, la ragione di questa restrizione è più stilistica che tecnica, e molte persone vorrebbero vederla rilassata .


9

I campi devono essere statici perché non possono essere astratti (come possono fare i metodi). Poiché non possono essere astratti, gli implementatori non saranno in grado di fornire logicamente la diversa implementazione dei campi.

I campi devono essere definitivi, penso, perché i campi possono essere acceduti da molti implementatori diversi, quindi possono essere modificabili potrebbe essere problematico (come la sincronizzazione). Anche per evitare che venga reimplementato (nascosto).

Solo il mio pensiero.


NawMan, la tua spiegazione su "I campi devono essere statici ..." non ha molto senso. Ma avevi ragione su "I campi devono essere definitivi ..."
picco

1
Non credo che abbia ragione sul motivo per cui i campi devono essere definitivi. Consentire a diversi implementatori di modificare un campo non è problematico, poiché altrimenti l'ereditarietà sarebbe problematica. I campi devono essere definitivi, come ha detto Adriaan, perché un'interfaccia è e dovrebbe essere senza stato. Un'interfaccia con uno stato dovrebbe fondamentalmente essere una classe astratta.
Axelle Ziegler

Se hai un public staticcampo che non lo è final, findbugs si lamenterà (giustamente!).
Tom Hawtin - tackline

2

Considero il requisito che i campi siano definitivi come indebitamente restrittivo e un errore dei progettisti del linguaggio Java. Ci sono momenti, ad esempio la gestione degli alberi, in cui è necessario impostare costanti nell'implementazione necessarie per eseguire operazioni su un oggetto del tipo di interfaccia. La selezione di un percorso di codice sulla classe di implementazione è un kludge. La soluzione alternativa che utilizzo è definire una funzione di interfaccia e implementarla restituendo un letterale:

public interface iMine {
    String __ImplementationConstant();
    ...
}

public class AClass implements iMine {
    public String __ImplementationConstant(){
        return "AClass value for the Implementation Constant";
    }
    ...
}

public class BClass implements iMine {
    public String __ImplementationConstant(){
        return "BClass value for the Implementation Constant";
    }
    ...
}

Tuttavia, sarebbe più semplice, più chiaro e meno incline a un'implementazione aberrante utilizzare questa sintassi:

public interface iMine {
    String __ImplementationConstant;
    ...
}

public class AClass implements iMine {
    public static String __ImplementationConstant =
        "AClass value for the Implementation Constant";
    ...
}

public class BClass implements iMine {
    public static String __ImplementationConstant =
        "BClass value for the Implementation Constant";
    ...
}

Sembra che ti lamenti più del fatto che i campi sono statici che definitivi.
Daniel Yankowsky

0

Specifiche, contratti ... L'istruzione macchina per l'accesso al campo utilizza l'indirizzo dell'oggetto più l'offset del campo. Poiché le classi possono implementare molte interfacce, non c'è modo di fare in modo che il campo dell'interfaccia non finale abbia lo stesso offset in tutte le classi che estendono questa interfaccia. Pertanto è necessario implementare un meccanismo diverso per l'accesso al campo: due accessi alla memoria (ottenere l'offset del campo, ottenere il valore del campo) invece di uno più il mantenimento del tipo di tabella del campo virtuale (analogo della tabella del metodo virtuale). Immagino che non volessero complicare jvm per funzionalità che possono essere facilmente simulate tramite roba (metodi) esistenti.

In scala possiamo avere campi nelle interfacce, sebbene internamente siano implementati come ho spiegato sopra (come metodi).


-1

static:

Nulla (variabile o metodo) che è staticin Java può essere invocata Classname.variablenameo Classname.methodnameo direttamente. Non è obbligatorio invocarlo solo utilizzando il nome dell'oggetto.

Nell'interfaccia, gli oggetti non possono essere dichiarati e staticrende possibile invocare variabili solo attraverso il nome della classe senza la necessità del nome dell'oggetto.

final:

Aiuta a mantenere un valore costante per una variabile in quanto non può essere sovrascritto nelle sue sottoclassi.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.