Nested/innere Klassen
Motivation
public class LinkedList {
private Node first;
public Object getFirst() {
if (first == null)
throw new NoSuchElementException();
return first.getItem();
}
...public class Node {
private Object item;
private Node next;
... - Klassen stark aneinander gekoppelt
Nodewird nur inLinkedListverwendet
Nested/static inner
public class Outer {
private static int staticVar;
private int instanceVar;
private static void staticMethod() {}
private void instanceMethod() {}
private static class Nested {
private static int nestedStaticVar;
private int nestedVar;
private void foo() {
staticVar++; βοΈ
staticMethod(); βοΈ
instanceVar++; π«
instanceMethod(); π«
}
}
public static void main(String[] args) {
Nested.nestedStaticVar++;
new Nested().nestedVar++;
new Outer.Nested().foo();
}
}
public class LinkedList {
Node first;
public Object getFirst() {
Node f = first;
if (f == null)
throw new NoSuchElementException();
return f.item;
}
private static class Node {
Object item;
Node next;
Node(Object item, Node next) {
this.item = item;
this.next = next;
}
}
}
- Einfacher Zugriff Outer -> Inner
- Outer mΓΆchte verstecken, dass Inner existiert
inner
public class Outer {
...
private class Inner {
private static int nestedStaticVar; π«
private int innerVar;
private void foo() {
staticVar++; βοΈ
staticMethod(); βοΈ
instanceVar++; βοΈ
instanceMethod(); βοΈ
}
}
public static void main(String[] args) {
new Outer.Inner(); π«
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
}
}
Einfacher Zugriff Outer <-> Inner
Local
button.setOnAction(EventHandler handler);@FunctionalInterface
public interface EventHandler extends EventListener {
void handle(Event event);
}
public void initialize(URL location, ResourceBundle resources) {
class CustomEventHandler implements EventHandler {
@Override
public void handle(Event event) {
foo();
}
}
Button button = new Button();
button.setOnAction(new CustomEventHandler());
}
Closure
public static void main(String[] args) {
String s = "Closure?";
class Local {
void foo() {
System.out.println(s); π«
}
}
s += "Object, welche den aktuellen Zustand kapselt";
}
Error: local variables referenced from an inner class must be final or effectively final
π±
Object foo() {
String s = "wtf";
class Local {
void foo() {
System.out.println(s);
}
}
return new Local();
}- Referenz
swird am Stack angelegt - Objekt
"wtf"muss erhalten bleiben - βΉ
Localmuss eine Referenz darauf haben
π± final π±
Object foo() {
String s = "wtf";
class Local {
void foo() {
System.out.println(s);
}
}
Object result = new Local();
Runnable mayHaveRun = () -> s = null; π«
mayHaveRun.start();
return result;
}
Anonym
public void initialize(URL location, ResourceBundle resources) {
Button button = new Button();
button.setOnAction(new EventHandler() {
@Override
public void handle(Event event) {
foo();
}
});
}public void initialize(URL location, ResourceBundle resources) {
Button button = new Button();
button.setOnAction(ev -> foo());
}
Best-practice
- Brauch ich nur eine Referenz?
- Anonyme innere Klasse
- Outer -> Inner
- nested
- Outer <-> Inner
- ganz sicher?
inner