API - Beispiel + static member in inner (non static) class

diggaa1984

Top Contributor
Hallo auch,

ich bastel mir da grad was zusammen und bin bei der Api der PriorityBlockingQueue auf folgendes gestossen:

Operations on this class make no guarantees about the ordering of elements with equal priority. If you need to enforce an ordering, you can define custom classes or comparators that use a secondary key to break ties in primary priority values. For example, here is a class that applies first-in-first-out tie-breaking to comparable elements. To use it, you would insert a new FIFOEntry(anEntry) instead of a plain entry object.

Java:
class FIFOEntry<E extends Comparable<? super E>> implements Comparable<FIFOEntry<E>> {
    final static AtomicLong seq = new AtomicLong();
    final long seqNum;
    final E entry;
   
    public FIFOEntry(E entry) {
        seqNum = seq.getAndIncrement();
        this.entry = entry;
    }
   
    public E getEntry() { 
        return entry; 
    }
   
    public int compareTo(FIFOEntry<E> other) {
        int res = entry.compareTo(other.entry);

        if (res == 0 && other.entry != this.entry)
            res = (seqNum < other.seqNum ? -1 : 1);

        return res;
    }
}

ich benutzte das Beispiel 1:1 als innere private klasse.
eclipse sage mir dann aber "static field seq can not be declared static; static fields can only be declared in static or top-level types"

ja soweit klar, füg ich also einfach ein static in der klassendeklaration ein, aber was bitte bringt ein "private static class" denn!? Und warum ist die Api dahingehend fehlerhaft?
 
Zuletzt bearbeitet:
ich benutzte das Beispiel 1:1 als innere private klasse.
eclipse sage mir dann aber "static field seq can not be declared static; static fields can only be declared in static or top-level types"

ja soweit klar, füg ich also einfach ein static in der klassendeklaration ein, aber was bitte bringt ein "private static class" denn!? Und warum ist die Api dahingehend fehlerhaft?
Das Beispiel aus der Dokumentation ist korrekt. Die dort beispielhaft vorgestellte Klasse ist nämlich ein "top-level type", und dort sind, wie die Fehlermeldung schon zum Ausdruck bringt, statische Felder erlaubt. Du hast das Beispiel aber als innere, nicht-statische Klasse wiederverwendet, deshalb der Fehler.

Ein "private static class" bringt vor allem eine Implementierung einer Schnittstelle oder eine Datenstruktur, die von der umgebenden Klasse benötigt wird.

Das [c]private[/c] garantiert, dass der Typ geheim (und nur für die umgebende Klasse zugänglich) bleibt.

Das [c]static[/c] garantiert, dass Instanzen dieser inneren Klasse nicht unmittelbar von der aktuellen Instanz der umgebenden Klasse abhängen können. Anders ausgedrückt: nicht-statische innere Klassen kennen neben ihrem eigenen [c]this[/c] auch das [c]this[/c] der umgebenden Klasse, sie nennen es [c]UmgebendeKlasse.this[/c]. (Statische innere Klassen kennen dagegen nur ihr eigenes [c]this[/c].)

Das "Problem" dabei, weshalb es zu dem Fehler kam: während das normale [c]this[/c] immer nur in objektgebundenen Methoden existiert, gibt es [c]UmgebendeKlasse.this[/c] praktisch immer und überall in der nicht-statischen inneren Klasse. Deswegen ist alles in einer solchen Klasse (insbesondere natürlich ihre Instanzen) immer an ein Objekt (nämlich [c]UmgebendeKlasse.this[/c]) gebunden und kann deshalb in keiner Weise (auch nicht nur zum Teil) irgendwie statisch sein.

Tipp: Mach alle inneren Klassen statisch, wenn möglich. Statische innere Klassen sind den "normalen" Klassen nämlich ähnlicher als ihre nicht-statischen Varianten. Vor allem [c]UmgebendeKlasse.this[/c] ist gerne mal ein Kandidat für Speicherlecks.

Beispiel: Du hast eine sehr große Instanz ("groß" bezogen auf den Speicherplatzverbrauch) einer Klasse. Weiterhin hat diese Klasse eine nicht-statische innere Klasse, von der du eine Instanz als Ergebnis irgendeiner Berechnung erzeugst und diese irgendwo nach draußen gibst (z.B., damit andere Objekte das Ergebnis haben). Das Problem hier: solange auch nur irgendein Objekt eine Referenz auf das Ergebnis dieser Berechnung hat, kann die besagte sehr große Instanz nicht gelöscht werden, weil diese nach wie vor vom Ergebnisobjekt referenziert wird, unabhängig davon, ob die sehr große Instanz für das Ergebnis notwendig ist oder nicht.

(Also zumindest denke ich, dass das so ist … 😳 )

Ark
 
ah super, am besten war der erste abschnitt 🙂

danke dir, soweit alles verstanden, irgendwie war es für mich zwingend, dass das Beispiel nur als innere Klasse gedacht war .. nuja, man lernt ja nie aus, richtig zu lesen 😀

danke dir
 

Neue Themen


Zurück
Oben