Was könnt Ihr mir alles über Innere-Klassen erzählen?
-
Kann mir jemand eine zusammenfassung zu inneren Klassen machen.
bitte keine links
bin für jeden Beitrag sehr dankbar
-
Gerne doch:
8.1.3 Inner Classes and Enclosing Instances
An inner class is a nested class that is not explicitly or implicitly declared static. Inner classes may not declare static initializers (§8.7) or member interfaces. Inner classes may not declare static members, unless they are compile-time constant fields (§15.28).To illustrate these rules, consider the example below:
class HasStatic{
static int j = 100;
}
class Outer{
class Inner extends HasStatic{
static final int x = 3; // ok - compile-time constant
static int y = 4; // compile-time error, an inner class
}
static class NestedButNotInner{
static int z = 5; // ok, not an inner class
}
interface NeverInner{} // interfaces are never inner
}
Inner classes may inherit static members that are not compile-time constants even though they may not declare them. Nested classes that are not inner classes may declare static members freely, in accordance with the usual rules of the Java programming language. Member interfaces (§8.5) are always implicitly static so they are never considered to be inner classes.A statement or expression occurs in a static context if and only if the innermost method, constructor, instance initializer, static initializer, field initializer, or explicit constructor invocation statement enclosing the statement or expression is a static method, a static initializer, the variable initializer of a static variable, or an explicit constructor invocation statement (§8.8.7).
An inner class C is a direct inner class of a class O if O is the immediately lexically enclosing class of C and the declaration of C does not occur in a static context. A class C is an inner class of class O if it is either a direct inner class of O or an inner class of an inner class of O.
A class O is the zeroth lexically enclosing class of itself. A class O is the nth lexically enclosing class of a class C if it is the immediately enclosing class of the n-1st lexically enclosing class of C.
An instance i of a direct inner class C of a class O is associated with an instance of O, known as the immediately enclosing instance of i. The immediately enclosing instance of an object, if any, is determined when the object is created (§15.9.2).
An object o is the zeroth lexically enclosing instance of itself. An object o is the nth lexically enclosing instance of an instance i if it is the immediately enclosing instance of the n-1st lexically enclosing instance of i.
When an inner class refers to an instance variable that is a member of a lexically enclosing class, the variable of the corresponding lexically enclosing instance is used. A blank final (§4.12.4) field of a lexically enclosing class may not be assigned within an inner class.
An instance of an inner class I whose declaration occurs in a static context has no lexically enclosing instances. However, if I is immediately declared within a static method or static initializer then I does have an enclosing block, which is the innermost block statement lexically enclosing the declaration of I.
Furthermore, for every superclass S of C which is itself a direct inner class of a class SO, there is an instance of SO associated with i, known as the immediately enclosing instance of i with respect to S. The immediately enclosing instance of an object with respect to its class' direct superclass, if any, is determined when the superclass constructor is invoked via an explicit constructor invocation statement.
Any local variable, formal method parameter or exception handler parameter used but not declared in an inner class must be declared final. Any local variable, used but not declared in an inner class must be definitely assigned (§16) before the body of the inner class.
Inner classes include local (§14.3), anonymous (§15.9.5) and non-static member classes (§8.5). Here are some examples:
class Outer {
int i = 100;
static void classMethod() {
final int l = 200;
class LocalInStaticContext{
int k = i; // compile-time error
int m = l; // ok
}
}void foo() {
class Local { // a local class
int j = i;
}
}
}The declaration of class LocalInStaticContext occurs in a static context-within the static method classMethod. Instance variables of class Outer are not available within the body of a static method. In particular, instance variables of Outer are not available inside the body of LocalInStaticContext. However, local variables from the surrounding method may be referred to without error (provided they are marked final).
Inner classes whose declarations do not occur in a static context may freely refer to the instance variables of their enclosing class. An instance variable is always defined with respect to an instance. In the case of instance variables of an enclosing class, the instance variable must be defined with respect to an enclosing instance of that class. So, for example, the class Local above has an enclosing instance of class Outer. As a further example:
class WithDeepNesting{
boolean toBe;
WithDeepNesting(boolean b) { toBe = b;}
class Nested {
boolean theQuestion;
class DeeplyNested {
DeeplyNested(){
theQuestion = toBe || !toBe;
}
}
}
}
Here, every instance of WithDeepNesting.Nested.DeeplyNested has an enclosing instance of class WithDeepNesting.Nested (its immediately enclosing instance) and an enclosing instance of class WithDeepNesting (its 2nd lexically enclosing instance).Noch Fragen?
-
ja, wozu benütigt man die eigentlich?
-
linjunky schrieb:
ja, wozu benütigt man die eigentlich?
(Die Frage ist doch schon konkreter.)
Man benutzt sie z.B. wenn Instanzen einer Klasse nur lokal in einer anderen (äußeren) Klasse benötigt werden und diese (innere Klasse) auf Member der äußeren zugreifen soll. Zum Beispiel könnte ein Server, der viele Connections gleichzeitig verwalten soll, eine innere Klasse Server.Connection definieren. Außerhalb von Server sind Connection-Objekte uninteressant, weswegen eine eigene Top-Level-Klasse unnötig wäre (Geheimnisprinzip).
Ein anderer Einsatz sind anonyme innere Klassen, wenn "ad hoc" ein Interface implementiert werden soll, z.B. ein Eventlistener oder ein Runnable für einen Thread.
-
interessant sind auch innere klassen mit privatem konstruktor. die sind zwar nach aussen hin sichtbar, man kann aber unter garantie davon ausgehen, dass sie stets nur von dieser einen äußeren klasse erzeugt wurden. gerade bei immutables kann man sich so einige sicherheitsmechanismen sparen, da man sie immer auch mit wohl definierten parametern konstruieren kann.
-
thibbek schrieb:
interessant sind auch innere klassen mit privatem konstruktor. die sind zwar nach aussen hin sichtbar, man kann aber unter garantie davon ausgehen, dass sie stets nur von dieser einen äußeren klasse erzeugt wurden. gerade bei immutables kann man sich so einige sicherheitsmechanismen sparen, da man sie immer auch mit wohl definierten parametern konstruieren kann.
public class Foo { private class Privat { private Privat() { } } public foo() { Privat privat = new Privat(); } }
Das geht ja
Ich hab immer gedacht, da der Konstruktor von Privat private ist, kann man ihn nicht mehr aufrufen.
-
DEvent schrieb:
Das geht ja
Ich hab immer gedacht, da der Konstruktor von Privat private ist, kann man ihn nicht mehr aufrufen.Richtig! Zumindestens nicht direkt!
-
public foo() { Privat privat = new Privat(); }
Was bringt das denn?
privat ist lokal und wird deshalb dem garbage collector
nach Beendigung der Methode, zum Fraß vorgeworfen!
-
Vielleicht passieren im Konstruktor ja die tollsten Sachen.
-
byto schrieb:
Vielleicht passieren im Konstruktor ja die tollsten Sachen.
Möglich. Dann hat man aber eine nutzlose lokale Variable, was die IDE anmeckern sollte. Dann schon lieber:
public foo() { new Privat(); }