Ich fand es wichtig, das Konzept des Entwerfens und Implementierens anonymer Klassen zu verstehen, um Stream-API zu lernen. Entwurf unter Verwendung von Methodenreferenzen, funktionalen Schnittstellen, Lambda-Ausdrücken und Generika (Instanzbereich und Methodenbereich, Entwurf basierend auf PECS-Prinzipien) Informieren Sie sich vor dem Lernen über anonyme innere Klassen, die als Gateway dienen.
In Blöcken ({}) deklarierte Klassen werden als "Nasted Classes" bezeichnet.
入れ子クラスのイメージ図.
NastedClazzSample.java
public class NastedClazzSample {
static class StaticClazz {} //static member class
class MemberClazz {} //menber class (inner class)
void method() {
class LocalClazz {} //local class (inner class)
}
}
Verschachtelte Klassen, die als Mitgliedsklassen deklariert sind, können Zugriffsmodifikatoren haben
NastedClazzSample.java
public class NastedClazzSample {
static protected class StaticClazz {} // OK
private class MemberClazz {} // OK
void method() {
public class LocalClazz {} // NG
}
}
Error.java
Das Qualifikationsmerkmal für die lokale Klasse LocalClazz ist falsch. Nur abstrakt oder endgültig erlaubt NastedClassSample.java /...(path)Zeile 11 Java-Problem
Aus irgendeinem Grund. Der Umfang lokaler Klassen ähnelt lokalen Variablen Greifen Sie im Beispiel über method () auf LocalClazz zu. Mit anderen Worten, es ist dasselbe wie der Accessor von method (), daher ist es nicht möglich, es zu beschreiben. </ Font>
Wie oben erwähnt, werden andere verschachtelte Klassen (nicht statische Elementklassen) als statische Elementklassen als innere Klassen bezeichnet.
Merkmale der inneren Klasse
- ① Kann keine statischen Elemente haben
Nicht statische Mitglieder sind Instanzen zugeordnet Lokale Variablen werden im Stapelbereich verwaltet und im Heapbereich platziert, wenn die Zielklasse instanziiert wird.
InnerClazzSample.java
public class InnerClazzSample {
public class Inner {
String foo;
}
public static void main(String... args) {
Inner inner = new InnerClazzSample().new Inner();
inner.foo = "bar";
System.out.println(inner.foo);
}
}
Ausführungsergebnis.java
bar
Bei Verwendung ohne Instanziierung
InnerClazzSample.java
public class InnerClazzSample {
public class Inner {
String foo;
}
public static void main(String... args) {
Inner.foo = "bar";
}
}
Error.java
Nicht statisches Feld Inner.Foo InnerClazzSample kann nicht statisch referenziert werden.java /~(path)Zeile 9 Java-Problem
Was ist die Bedeutung davon.
Zunächst liest die JVM die von der Anwendung verwendeten Klassen und erweitert sie im Speicher. Zu diesem Zeitpunkt befindet sich das statische Element in einem Speicherbereich (Klassenbereich), der sich vom nicht statischen Element unterscheidet. Der Bootstrap-Klassenlader wird beim JVM-Start aufgerufen, aber anstatt alle Klassen zu laden, wird er geladen, wenn eine Klassenreferenz aus der Anwendung vorhanden ist. Sie können auch den Bereich der Klassensätze ändern, die geladen werden können, indem Sie -Xbootclasspath ändern.
statische Elemente sind Klassen zugeordnet. Der Zeitpunkt der Speichererweiterung hängt von der JVM-Implementierung ab. </ Font>
Outer.java
public class Outer {
private int foo;
public class Inner {
public int bar;
private void method() {
this.foo = Outer.this.bar; // OK
}
}
private void method() {
this.foo = bar; // NG
}
}
Die Instanzpriorität nicht statischer innerer Klassen ist ebenfalls
- Lokale Variable des Anrufers
Outer.java
public class Outer {
String foo = "outerclass-a";
String bar = "outerclass-b";
String baz = "outerclass-c";
public class Inner {
String foo = "innerclass-a";
String bar = "innerclass-b";
public void thread() {
String foo = "thread-c";
System.out.println(foo);
System.out.println(bar);
System.out.println(baz);
System.out.println(this.foo);
System.out.println(Outer.this.foo);
}
}
public static void main(String... args) {
new Outer().new Inner().thread();
}
}
Ausführungsergebnis.java
thread-c
innerclass-b
outerclass-c
innerclass-a
outerclass-a
Wenn Sie eine verschachtelte Klasse verwenden, kann diese als Klasse ohne Namen verwendet werden Solche verschachtelten Klassen werden "anonyme Klassen" genannt.
Wird hauptsächlich für folgende Zwecke verwendet
Anonyme Klasse-Syntax 1.text
neuer Typname() {
Implementierung abstrakter Methoden
}
Anonyme Klasse-Syntax 2.text
Typname Instanzname=neuer Typname() {
Implementierung abstrakter Methoden
}
Implementieren Sie zunächst die abstrakte Methode der Schnittstelle, ohne die anonyme Klasse zu verwenden.
Sample.java
interface FooInterface { //interface
void method(); //abstract method
}
class BarClazz implements FooInterface { //implemented class
public void method() {
System.out.println("Did Implementation"); //implemented abstract method
}
}
public class Sample{ //runner
public static void main(String... args) {
new BarClazz().method(); //new instance
}
}
Bei der Implementierung einer abstrakten Methode mit einer anonymen Klasse
Sample.java
interface FooInterface {
void method();
}
//nothing inplemented class
public class Sample {
public static void main(String... args) {
FooInterface foo = new FooInterface() { //anonymous class
public void method() {
System.out.println("Did Implementation"); //implemented abstract method
}
}; //semi-coron
foo.method(); //instance.method()
}
}
Ausführungsergebnis.java
Did Implementation
Betrachten Sie ein praktisches Beispiel einer anonymen Klasse
① Wenn die Wiederverwendbarkeit der Verarbeitung gering ist und nur vor Ort erforderlich ist
Definieren Sie eine Klasse, die Kundeninformationen verwaltet
ManagementClientInformation.java
public class ManagementClientInformation {
public static class Client {
private int id;
private String name;
Client(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return this.id;
}
public String getName() {
return this.name;
}
}
public static void main(String... args) {
List<Client> clientList = new ArrayList<>();
clientList.add(new Client(1, "matsuda"));
clientList.add(new Client(2, "tanaka"));
clientList.add(new Client(3, "neko"));
clientList.stream()
.forEach(x -> System.out.println(x.getId() + " " + x.getName()));
}
}
Ausführungsergebnis.java
1 matsuda
2 tanaka
3 neko
Betrachten Sie die folgenden Ereignisse
Sie sind Systemingenieur Während der Wartung / Reparatur gab es eine Anfrage eines Kunden Es wird angefordert, einen bestimmten Bildschirm in umgekehrter Reihenfolge der Kunden-ID zu sortieren Darüber hinaus ist es verboten, die Client-Klasse zu ändern, da Bedenken hinsichtlich der Auswirkungen auf das System und des Aufblähens bestehen.
⇒ Verwenden Sie eine anonyme Klasse
ManagementClientInformation.java
public class ManagementClientInformation {
public static class Client {
private int id;
private String name;
Client(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return this.id;
}
public String getName() {
return this.name;
}
}
public static void main(String... args) {
List<Client> clientList = new ArrayList<>();
clientList.add(new Client(1, "matsuda"));
clientList.add(new Client(2, "tanaka"));
clientList.add(new Client(3, "neko"));
Collections.sort(clientList, new Comparator<Client>() {
public int compare(Client c1, Client c2) {
return Integer.compare(c2.getId(), c1.getId());
}
});
clientList.stream()
.forEach(x -> System.out.println(x.getId() + " " + x.getName()));
}
}
Ausführungsergebnis.java
3 neko
2 tanaka
1 matsuda
Als ich Stream API zum ersten Mal berührte, verstand ich den Inhalt überhaupt nicht. Während ich es tat, vertiefte ich allmählich mein Verständnis, als ich die Methodenreferenz ⇒ Lambda-Ausdruck ⇒ Generika-Design in umgekehrter Reihenfolge lernte. Ich möchte es anwenden, nachdem ich den grundlegenden Teil fest verstanden habe.
Recommended Posts