2009-10-03 6 views
86

Ich versuche nur zu verstehen, warum alle in einer Schnittstelle definierten Felder implizit static und final sind. Die Idee, Felder static zu behalten, macht für mich Sinn, da Sie keine Objekte einer Schnittstelle haben können, sondern warum sie final (implizit) sind?Warum sind alle Felder in einer Schnittstelle implizit statisch und final?

Jeder weiß, warum Java-Designer gingen mit der Erstellung der Felder in einer Schnittstelle static und final?

Antwort

115

Eine Schnittstelle kann kein Verhalten oder Status haben, da nur ein Interaktionsvertrag angegeben werden soll, keine Implementierungsdetails. Kein Verhalten wird erzwungen, indem keine Methoden/Konstruktor-Bodies oder statische/Instanz-initialisierende Blöcke zugelassen werden. Kein Zustand wird erzwungen, indem nur statische Endfelder zugelassen werden. Daher kann die Klasse einen Status (statischer Zustand) haben, der Instanzstatus wird jedoch von der Schnittstelle nicht abgeleitet.

BTW: Eine Konstante in Java wird durch ein statisches Endfeld definiert (und der Name verwendet per Konvention UPPER_CASE_AND_UNDERSCORES).

+47

Es ist nicht unbedingt wahr, dass letzte Felder Konstanten sind; das ist nur für primitive Typen garantiert. Im Allgemeinen bedeutet das letzte Schlüsselwort lediglich, dass sich der Speicherort nicht ändert. – Pops

+7

Ich habe nicht gesagt, letzte Felder sind Konstanten, nur dass Konstanten endgültige Felder sind. Beachten Sie, dass es erlaubt ist, ein nicht primitives statisches Endfeld in einer Schnittstelle zu platzieren. Auch wenn sich der Inhalt dieses Felds ändert, ist der Verweis darauf konstant. –

+1

@AdriaanKoster Sie haben genau gesagt, dass das letzte Feld konstant ist: * Kein Zustand wird erzwungen, indem nur Konstanten zugelassen werden. * - dieser Satz impliziert, dass alle letzten Felder konstant sind. Sie könnten versuchen, weiter über die von Ihnen verwendeten Wörter zu streiten, aber Ihre Aussage ist offensichtlich irreführend. –

9

Die Felder müssen statisch sein, da sie nicht abstrakt sein können (wie Methoden). Da sie nicht abstrakt sein können, sind die Implementierer nicht in der Lage, die verschiedenen Implementierungen der Felder logisch bereitzustellen.

Die Felder müssen endgültig sein, denke ich, weil die Felder von vielen verschiedenen Implementierern zugegriffen werden können, können sie änderbar sein, könnte problematisch sein (als Synchronisation). Auch um zu vermeiden, dass es neu implementiert (versteckt) wird.

Nur mein Gedanke.

+0

NawMan, Ihre Erklärung über "Die Felder müssen statisch sein ..." macht wenig Sinn. Aber du hattest recht mit dem "Die Felder müssen endgültig sein ..." – peakit

+1

Ich glaube nicht, dass er recht hat mit dem Grund, warum die Felder endgültig sein müssen. Es ist unproblematisch, es verschiedenen Implementierern zu erlauben, ein Feld zu ändern, da andernfalls die Vererbung problematisch wäre. Felder müssen endgültig sein, wie Adriaan sagte, weil eine Schnittstelle zustandslos ist und sein sollte. Eine Schnittstelle zu einem Staat sollte grundsätzlich eine abstrakte Klasse sein. –

+0

Wenn Sie ein "öffentliches statisches" Feld haben, das nicht "final" ist, werden sich Findbugs beschweren (zu Recht!). –

16

Es gibt ein paar Punkte hier beschönigt:

Nur weil Felder in einer Schnittstelle implizit statisch sind endgültig bedeutet nicht, müssen sie Kompilierung-Konstanten sein oder sogar unveränderlich. Sie können z.B.

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

(Beachten Sie, dass diese in einer Anmerkungs Definition Dadurch kann confuse javac, auf die Tatsache bezieht, dass die oben kompiliert tatsächlich zu einem statischen Initialisierer.)

, auch der Grund für diese Einschränkung ist, mehr stilistisch als technisch, und viele Leute würden like to see it be relaxed.

20

Daseins final

Irgendwelche Implementierungen Wert von Feldern ändern, wenn sie nicht als endgültig definiert sind. Dann würden sie Teil der Implementierung werden. Eine Schnittstelle ist eine reine Spezifikation ohne jegliche Implementierung.

GRUND static

FÜR werden, wenn sie statisch sind, dann gehören sie an die Schnittstelle, und nicht das Objekt, noch die Laufzeittyp des Objekts.

2

Ich halte die Anforderung, dass die Felder endgültig als übermäßig restriktiv und ein Fehler durch die Java-Sprache Designer. Es gibt Zeiten, z.B. Baumbehandlung, wenn Sie in der Implementierung Konstanten setzen müssen, die Operationen an einem Objekt des Schnittstellentyps ausführen müssen. Das Auswählen eines Codepfads für die implementierende Klasse ist ein Kludding.Die Abhilfe, die ich benutze, ist eine Schnittstellenfunktion zu definieren und umzusetzen, indem eine wörtliche Rückkehr:

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"; 
    } 
    ... 
} 

Allerdings wäre es zu abweichender Implementierung einfacher, klarer und weniger anfällig für diese Syntax zu verwenden:

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"; 
    ... 
} 
+0

Sie scheinen sich mehr darüber zu beschweren, dass die Felder statisch sind als endgültig. –

0

Spezifikation, Kontrakte ... Die Maschinenanweisung für den Feldzugriff verwendet Objektadresse plus Feldoffset. Da Klassen viele Schnittstellen implementieren können, gibt es keine Möglichkeit, ein nicht endgültiges Schnittstellenfeld in allen Klassen, die diese Schnittstelle erweitern, mit dem gleichen Offset zu versehen. Daher müssen verschiedene Mechanismen für den Feldzugriff implementiert werden: zwei Speicherzugriffe (Feldoffset erhalten, Feldwert holen) anstelle von einem plus die Art der virtuellen Feldtabelle (analog der virtuellen Methodentabelle). Vermute, sie wollten jvm einfach nicht für Funktionalität komplizieren, die einfach über existierende Sachen (Methoden) simuliert werden kann.

In Scala können wir Felder in Schnittstellen haben, obwohl sie intern implementiert sind, wie ich oben (als Methoden) erklärt habe.

-1

static:

Alles (variable oder Methode), die in Java static ist, kann als Classname.variablename oder Classname.methodname oder direkt aufgerufen werden. Es ist nicht zwingend erforderlich, sie nur über den Objektnamen aufzurufen.

In der Schnittstelle können Objekte nicht deklariert werden, und static ermöglicht es, Variablen nur über den Klassennamen ohne den Objektnamen aufzurufen.

final:

Es hilft, einen konstanten Wert für eine Variable zu halten, da sie nicht in ihren Unterklassen außer Kraft gesetzt werden kann.