Innere Klasse und final

Status
Nicht offen für weitere Antworten.

WeirdAl

Bekanntes Mitglied
Hallo,
ich habe eine Verständnisfrage zum Thema Innere Klassen.

Wenn ich von einer Inneren Klasse aus auf eine lokale Variable der Äußeren Klasse zugreifen möchte, geht dies ja nur wenn diese als final deklariert ist.

Meine Frage lautet jetzt: Warum ist das so?

Cu
Alex
 

quippy

Bekanntes Mitglied
Nach meinem Verständnis ist das folgendermaßen (kein Anspruch, daß das korrekt ist):

final deklarierte Variablen MÜSSEN initialisiert werden - ihr Wert kann sich danach nicht mehr ändern. Da inner-Classes möglicherweise nicht wissen, wer ihre Vater-Instanz ist, können Sie nicht direkt auf den Inhalt der Variablen zugreifen, er muss daher wahrscheinlich fest initialisiert sein (Quasi konstant), um dann in die Inner Class beim Instantiieren derselben hineinkopiert zu werden.

Näheres könnte man erfahren, wenn man sich den Bytecode ansieht.

Um das Problem zu umgehen, würde ich der InnerClass einen Konstruktor oder eine Setter spendieren, der man die Vater-Instanz mitgibt. Dann könntest Du den benötigten Wert per Getter der Inner-Class zur Verfügung stellen.
 
S

SlaterB

Gast
> er muss daher wahrscheinlich fest initialisiert sein (Quasi konstant),

stimmt nicht, es kann auch ein finaler Parameter der Operation
oder final double d = Math.random(); oder sonstwas sein,

> final deklarierte Variablen MÜSSEN initialisiert werden

lokale Variablen müssen sowieso alle vor Gebrauch initialisiert werden, auch in normalen Code,
mit Exemplarvariablen/ Klassenattributen gehts übrigens auch nicht-final, das Vater-Objekt ist also bekannt

-----------

für mich gibt es keinen logischen Grund, warum das so gebaut ist,
außer, den Programmier etwas zu lenken, so dass eindeutig ist, welcher Wert in die innere Klasse kommt

Code:
public class Test
{
    public static void main(String[] args)
    {
        for (int i = 0; i < 5; i++)
        {
            final int finalI = i;
            Object o = new Object()
                {
                    public String toString()
                    {
                        return "i: " + finalI;
                    }
                };
            System.out.println(o);
        }
    }
}
funktioniert, warum direkt mit i nicht?
diesen Standard 'Variablen nehmen, als final deklarieren, in innerer Klasse auf finale Variable zugreifen' könnte der Compiler genausogut, da ist nix besonderes dabei,

allein um dies nicht zu verstecken, sondern den User sichtbar zu machen,
wird es dem User aufgebunden, nehme ich an
 

quippy

Bekanntes Mitglied
Das ist genau das, was ich meine, denn für deine anonyme Klasse ist "finalI" dann konstant (deswegen "quasi konstant")
 
S

SlaterB

Gast
ja und? jede Variable ist zwischen zwei Änderungen quasi-konstant..
welchen Sinn hat diese Aussage?
wenn ich eine Unteroperation aufrufe, dann ist für diese Zeit der Parameter ja quasi auch konstant..


----------
aber immerhin kommt noch dazu, dass man nicht anfangen sollte, in der inneren Klasse die Variable zu ändern,

das wäre aber einfacher zu prüfen, indem man solche Versuche in der inneren Klasse anstreicht
(Variable i is constant in inner class, do not modify)
 

quippy

Bekanntes Mitglied
Nun ich hatte halt den Tipp abgegeben, daß inner Classes auf Variablen außerhalb nicht per Referenz zugreifen können - vielleicht, weil die Adresse außerhalb ihres Scopes liegt.

Daher wird vielleicht der Inhalt wohl bei Zugriff auf die Klasse dort hin kopiert. Daher darf sich der Inhalt der Variablen außerhalb nicht ändern, was er natürlich jederzeit könnte. Durch die "final" deklaration wird das explizit verhindert, so daß man davon ausgehen kann, daß sich "finalI" nie nie niemlas zwischen dessen Deklaration/einmaliger Definition und dem Aufruf in die anonyme Inner Class ändert wird.

Deine Alternative mit der Warnung würde zwar auf eine mögliche Gefahrenquelle hindeuten, aber nicht explizit verhindern, was zu Problemen führen könnte.

Mit der gleichen Logik könnte ich auch die Sichtbarkeitsregeln abschaffen, frei nach dem Motto: auf Membervariablen mit spendierter Zugriffs-Methode greift man nie direkt zu - selbst, wenn man es kann. Das bedeutet eben, daß sich Entwickler verantwortungsvoll mit dem Code auseinandersetzen. Und das tun i.d.R. nur noch wenige!
 
S

SlaterB

Gast
gut, so gesehen macht es Sinn,
das entspricht ja meine Erklärung 'den Programmier etwas zu lenken, so dass eindeutig ist, welcher Wert in die innere Klasse kommt'

hat nix mit Initalisierung oder anderen technischen Gründen zu tun,
ein purer Nerv-Faktor für den User, der dafür falsche Vorstellungen erspart
 

quippy

Bekanntes Mitglied
Hey, vielen Dank, Joe!

Hier die Essenz zum aktuellen Problem daraus, für die, die nicht alles lesen wollen:
The rule is anonymous inner classes may only access final local variables of the enclosing method. Why? Because the inner class’s methods may be invoked later, long after the method that spawned it has terminated, e.g. by an AWT event. The local variables are long gone. The anonymous class then must work with flash frozen copies of just the ones it needs squirreled away covertly by the compiler in the anonymous inner class object.

You might ask, why do the local variables have to be final? Could not the compiler just as well take a copy of non-final local variables, much the way it does for a non-final parameters? If it did so, you would have two copies of the variable. Each could change independently, much like caller and callee’s copy of a parameter, however you would use the same syntax to access either copy. This would be confusing. So Sun insisted the local be final. This makes irrelevant that there are actually two copies of it.

Und ja, da fällt einem auf, daß gerade z.B. bei einem ActionListener zum Zeitpunkt dessen Aufrufs die ggf. referenzierte Variable ja gar nicht mehr da ist.
Also wird sie tatsächlich in die Klasse hineinkopiert - und da dann zwei Varianten existieren, die unabhängig geändert werden könnten, sollen sie "final" sein - damit genau das nicht passiert.
 

Der Müde Joe

Top Contributor
Ums noch etwas zu konkretisieren:

Der Heap dient zur Spreicherung von dynamischen Informationen über konkrete Objekte.
Dazu gehören auch Innere.

Nun Methoden speicher ihre lokalen Variablen aber im Stack ab. Kommt man in eine
Methode rein, wird ein Frame in den Stack gepushed, verlässt man die Methode (retun, Exception)
wird das FRame wieder von Stack genommen.

Nun das final bewirkt, dass die lokale Variable nicht in den Stack des entsrechenden Threads
geschrieben wird, sonder tiefer, also auf den Heap gelegt wird.

Somit bleibt diese Variable für die innere Klasse verlässlich erhalten.

(hoffe blabere keinen Müll) :wink:
 
S

SlaterB

Gast
> Somit bleibt diese Variable für die innere Klasse verlässlich erhalten.

werden alle final Variablen für alle Zeit irgendwo abgespeichert?
dann ist der Speicher ja irgendwann voll ;)

dass die Variable gespeichert wird hat nix mit final, Heap, Stack oder sonstigen lustigen Wörtern zu tun,
das macht Java (irgendwie) und fertig ist die Geschichte

final wie gesagt allein um den User zu lenken, dass er nicht denkt, dass die Variable noch geändert werden kann
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
I Collection - contains-Methode überschreiben (anonyme innere Klasse) Allgemeine Java-Themen 4
F Enums als innere Klasse sinnvoll? Allgemeine Java-Themen 3
S Zugriff auf innere Klasse Allgemeine Java-Themen 3
S Innere Klasse: Zugriff auf äußere Variable Allgemeine Java-Themen 5
G innere Erzeuger- Klasse Allgemeine Java-Themen 5
P innere Klasse auflösen Allgemeine Java-Themen 5
S Konzept: Innere Klasse, Anwendungsbeispiel? Allgemeine Java-Themen 4
Q Der innere Typ von Generics? Allgemeine Java-Themen 3
C Innere Klassen und UML Allgemeine Java-Themen 3
S Innere Klassen und die statische Methode access$x Allgemeine Java-Themen 5
O Verschachtelte Iteration: Innere Iteration abbrechen Allgemeine Java-Themen 3
C Innere Klassen zur Laufzeit Instanzieren Allgemeine Java-Themen 4
M innere Klassen - EJB 2.x Allgemeine Java-Themen 6
F Innere Klassen Allgemeine Java-Themen 4
K Reflection:Zugriff auf innere Klassen Allgemeine Java-Themen 4
A Eventhandler: innere Klassen vs. "normale Klassen" Allgemeine Java-Themen 3
E Innere Klassen Allgemeine Java-Themen 3
B Innere Methoden Allgemeine Java-Themen 2
B Zugriff auf innere Methoden Allgemeine Java-Themen 4
M Methodenübersicht einer Klasse einsehen Allgemeine Java-Themen 14
Jose05 Java-Klasse im extra cmd-Fenster ausführen Allgemeine Java-Themen 3
torresbig Klasse mit extends Calendar über Methoden ändern (Hirnblockade) Allgemeine Java-Themen 7
A Zweite Service Klasse beim Kompilieren Allgemeine Java-Themen 6
B Ein Objekt einer Klasse mehreren anderen Klassen zur Verfügung stellen? Allgemeine Java-Themen 6
Atten007 Java-Klasse auf macOS entpacken? Allgemeine Java-Themen 2
M Klasse durch Klassen Aufteilung verbessern, aber wo? Allgemeine Java-Themen 1
E Eine Methode einer extendeten Klasse deakitivieren Allgemeine Java-Themen 12
H Kombination Interface und Abstrakte Klasse bei Generics Allgemeine Java-Themen 3
EinNickname9 Best Practice Singleton und Singleton mit Instanz zu anderer Klasse -Pattern Allgemeine Java-Themen 30
Y ImagePanel von anderer Klasse in eine MainFrame Klasse hinzufügen. Allgemeine Java-Themen 1
Lukas2904 Schleife mit ansteuerung einer Klasse Allgemeine Java-Themen 5
d.lumpi Aus Einer Klasse auf ein Objekt einer anderen Klasse Zugreifen Allgemeine Java-Themen 1
missy72 Klassen Eigene Klasse MessageWindow ähnlich der Alert Klasse Allgemeine Java-Themen 2
Drachenbauer wie kann ich alle instanzen einer Klasse durchsehen, ohne, dass diese in einer Liste erzeugt wurden? Allgemeine Java-Themen 11
kanywayne Java programmieren: Polynom Klasse Allgemeine Java-Themen 4
L Die abzuleitende Klasse als Parameter übergeben Allgemeine Java-Themen 4
S Klassen Einfügen von unbekannter menge an Variablen in eine Klasse mithilfe von ASM Allgemeine Java-Themen 5
C Klasse mit Mockito simulieren Allgemeine Java-Themen 9
P einen public <Optinal String> in einer anderen Klasse mit einem Int vergleichen Allgemeine Java-Themen 2
S Wenn eine Klasse zwei Interfaces mit derselben Methodensignatur implementiert: welche wird aufgerufen? Allgemeine Java-Themen 15
Thallius Key/Value Table in Klasse einlesen Allgemeine Java-Themen 14
S static in Interface und Klasse Allgemeine Java-Themen 2
W Was genau sind IOTools? Kann ich stattdessen nicht die Scanner Klasse verwenden? Allgemeine Java-Themen 3
V Threads Probleme beim Aufrufen von Methoden einer anderen Klasse (Threads) Allgemeine Java-Themen 14
X Collections Gibt es eine Klasse welche die Vorteile von List und HashMap vereint, aber konstante Laufzeit (O(1)) hat in Java? Allgemeine Java-Themen 4
D javassist API Klasse in MethodCall ermitteln Allgemeine Java-Themen 8
kodela Klasse mit "gezipten" Daten Allgemeine Java-Themen 6
J Builder Klasse mit Lombok bauen Allgemeine Java-Themen 2
L Operatoren Java Reflections: Alle Methoden einer Klasse aufrufen ohne Exceptions Allgemeine Java-Themen 5
M [SOAP] - Klasse aus WSDL ausschließen Allgemeine Java-Themen 2
N Generic Type einer Generischen Klasse während der Laufzeit bekommen Allgemeine Java-Themen 2
X Klassen Klasse BreakIterator Allgemeine Java-Themen 6
R Arraylist in andere Klasse leiten und bearbeiten Allgemeine Java-Themen 10
kodela Klassen Klasse "vergisst" ihre Daten Allgemeine Java-Themen 2
pkm Kann eine ServerSocket-Klasse nicht stateful sein? Allgemeine Java-Themen 4
E Socket Dynamische Klasse von ObjectOutputStream lesen. Allgemeine Java-Themen 8
M Matcher-Klasse findet match nicht Allgemeine Java-Themen 6
cool_brivk24 Variablen abfragen von Boolean von anderer Klasse Allgemeine Java-Themen 12
S Seltsames Ergebnis mit Date-Klasse Allgemeine Java-Themen 6
J int Werte in einer anderen Klasse in Arrays speichern Allgemeine Java-Themen 3
D Warum kann ich eine (deflaut) Klasse aus einer Libary in einem anderen Projekt benutzen? Allgemeine Java-Themen 3
Neoline Klassen Singleton Klasse buchmanager Allgemeine Java-Themen 19
M Kapselung Modellierung von Intervallen: Klasse Interval Allgemeine Java-Themen 4
B Übernommene Variablen(werte) aus der Main-Klasse ändern? Allgemeine Java-Themen 9
ReinerCoder Klasse kann nicht public deklariert werden Allgemeine Java-Themen 2
ReinerCoder Methode einer Klasse meldet Fehler "misplaced construct(s)" Allgemeine Java-Themen 13
X Klassen File-Klasse wird als Directory markiert Allgemeine Java-Themen 8
S Methoden Liste soll Methode aus innerer Klasse aufrufen Allgemeine Java-Themen 4
J IndexOutOfBoundsException bei der Nutzung der Klasse Message von mime4j Allgemeine Java-Themen 5
P Array einer abstrakten Klasse Allgemeine Java-Themen 4
J Zugriff auf erstellte Objekte einer Klasse von einer Klasse ausserhalb Allgemeine Java-Themen 3
kodela Dynamisches Array in einer Klasse Allgemeine Java-Themen 5
M Was geschieht mit Java-Klasse, die aus ArrayList entfernt wird? Allgemeine Java-Themen 10
perlenfischer1984 Lombok Builder soll andere Klasse bauen Allgemeine Java-Themen 4
perlenfischer1984 Mit Lombok Builder Felder in Super Klasse füllen Allgemeine Java-Themen 12
T String aus While Schleife für ganze Klasse sichtbar machen Allgemeine Java-Themen 5
K Best Practice Auf die Klasse zugreifen im erzeugten ActionListener Allgemeine Java-Themen 2
K Mit Button neue Klasse öffnen Allgemeine Java-Themen 9
J Reflection mit Klasse und Subklasse Allgemeine Java-Themen 11
C Classpath Neue Klasse über einen Button ausführen Allgemeine Java-Themen 3
magdaStone Logikproblem Umschalten von booleans in anderer Klasse Allgemeine Java-Themen 7
P mehrer Verschiedene Objekte in einer Klasse erstellen. Allgemeine Java-Themen 4
A Java Klasse auf Tomcat während der Laufzeit austauschen Allgemeine Java-Themen 1
C Abstrakte Klasse, lokale Variable-Problem Allgemeine Java-Themen 1
N Vererbung Design-Problem mit vorhandenen, von der Klasse unabhängigen Methoden Allgemeine Java-Themen 12
Messoras Klassen Sämtliche Variablen einer Klasse übernehmen Allgemeine Java-Themen 6
H Methoden Methode 'updateItem' der Klasse 'TreeCell' Allgemeine Java-Themen 3
B Animierte Klasse schreiben - Wie? Allgemeine Java-Themen 9
M Klassen Eine Klasse in mehreren Klassen einbinden Allgemeine Java-Themen 11
N Methoden Methoden einer Klasse auf Grundlage eines Strings aufrufen Allgemeine Java-Themen 6
AssELAss Log4j Logging Ausgabe für jede Klasse in seperates File Allgemeine Java-Themen 2
L Eclipse JavaFX Klasse starten programmatisch Allgemeine Java-Themen 1
F Try/catch über ganze Klasse Allgemeine Java-Themen 9
L Von ArrayList abgeleitete Klasse nur mit bestimmten Objekten füllen Allgemeine Java-Themen 1
so_ein_Komischer Erste Schritte java Math Klasse finden? Allgemeine Java-Themen 2
J beans.instantiate(): Klasse kann nicht instanziiert werden Allgemeine Java-Themen 2
I Interface Interface / Klasse - wieso Abstract? Allgemeine Java-Themen 13
R Abstrakte Basisklasse und instanzierte Objekte der abgeleiteten Klasse als Basisklasse übergeben Allgemeine Java-Themen 2
F Methodenaufruf mit abgeleiteter Klasse als Arg... Allgemeine Java-Themen 10
M Klasse in separaten Thread ausführen.Wie genau? Allgemeine Java-Themen 2

Ähnliche Java Themen

Neue Themen


Oben