Infrastructure Shop wird Java erneut studieren (1. Klasse)

Eine Geschichte über ein Infrastrukturunternehmen, das vor mehr als 10 Jahren nur etwa drei Monate lang Java in der Ausbildung gelernt hat und auf Java Gold abzielt. [Dieses Buch](https://books.google.co.jp/books?id=N0ktDQAAQBAJ&printsec=frontcover&dq=java+gold&hl=ja&sa=X&ved=0ahUKEwjO7_LEv5PZAhXFKZQKHeI-AIQQ6EI-AIQ Basierend auf v = onepage & q = java% 20gold & f = false) werde ich die wichtigsten Punkte auf meine eigene Weise zusammenfassen. Das erste ist Klassendesign.

Verkapselung

Beispiel


class Hoge {
    private int hoge;
    public Hoge(int hoge) { this.hoge = hoge; }

    /*accessor*/
    //setter
    public void setHoge(int hoge) {
        //check
        if(check) this.hoge = hoge;
    }
    //getter
    public int getHoge() { return hoge; }
}

Das Folgende ist eine Zusammenfassung anderer Zugriffsmodifikatoren als "privat" und ihrer Auswirkungen.

Zugriffsmodifikatoren und Gültigkeitsbereich

Zugriffsmodifikatoren Klasse Paket Unterklasse Andere (alle)
public o o o o
protected o o o x
Nicht angegeben (Standard) o o x x
private o x x x

Referenzdokument

Class Modifiers Zusammenfassung der (Klassen-) Modifikatoren.

abstract Zeigt eine unvollständige (denkbare) Klasse an. Kompilierungsfehler beim Versuch, eine Instanz aus der abstrakten Klasse zu erstellen. Wenn es der Methode gegeben wird, bedeutet dies, dass es nicht implementiert ist. Die abstrakte Methode kann nur in der abstrakten Klasse definiert (deklariert) werden (Kompilierungsfehler (a), wenn die abstrakte Methode in einer normalen Klasse geschrieben ist). Im Gegenteil, wenn Sie eine abstrakte Klasse mit einer abstrakten Methode erben und diese abstrakte Methode nicht überschreiben (implementieren), müssen Sie immer die abstrakte Klasse verwenden (Kompilierungsfehler (b)). ~~ Selbst wenn Sie eine abstrakte Methode mit derselben Methodensignatur deklarieren, die in der Schnittstelle in der abstrakten Klasse deklariert ist, die die Schnittstelle implementiert, tritt ein Kompilierungsfehler auf ~~ [saka1029-sama Wie im Kommentar 2018.02.11 ausgeführt [Fix] In der abstrakten Klasse, die die Schnittstelle implementiert, ist es möglich, sie als abstrakt zu belassen, ohne die Methode (@Override) zu implementieren. Da die Sichtbarkeit jedoch nicht verringert werden kann, tritt ein Kompilierungsfehler auf, wenn Sie vergessen, public einzugeben (c).

Kompilierungsfehler(a)


abstract class Hoge {
    abstract void doHoge();
}
class Hoge2  {
    public void doHoge2() {
        Hoge hoge = new Hoge();  //Kompilierungsfehler, weil Sie versuchen, eine abstrakte Klasse zu instanziieren
    }
}

Kompilierungsfehler(b)


abstract class abstractHoge {
    abstract void doHoge();
}
class Hoge extends abstractHoge {
    public void hoge() { } //abstrakte Methode (doHoge()) Bleibt, aber es ist nicht abstrakt, also ein Kompilierungsfehler
}

Kompilierungsfehler(c)


interface HogeInterface {
    void doHoge(int hoge);
}
abstract class abstractHoge implements HogeInterface {
    abstract void doHoge(int hoge);    //Da die Schnittstellenmethode und die von der Signatur abgedeckte abstrakte Methode deklariert sind, wird im Kommentar von saka1029 auf einen Kompilierungsfehler hingewiesen →[2018.02.11 Korrektur]Selbst wenn die Signatur abgedeckt ist, handelt es sich nur um eine Erklärung, die einfach mets, aber dennoch abstrakt ist und kompiliert werden kann. Kompilierungsfehler, dass die in der Schnittstelle deklarierte Methode nicht in der Sichtbarkeit reduziert werden kann, da sie implizit öffentlich ist und hier nicht öffentlich ist.
}

final Es zeigt, dass fast alle Klassen sind, die nicht mehr vererbt werden können. Kompilierungsfehler (a) beim Versuch, die letzte Klasse zu erweitern. Kompilierungsfehler bei gleichzeitiger Verwendung von Abstract und Final (eindeutig inkonsistent bei Verwendung von Abstract, das erweitert werden soll, und Final, das nicht gleichzeitig erweitert werden kann) (b).

Kompilierungsfehler(a)


final class finalHoge { }
class SubHoge extends finalHoge { } //Kompilierungsfehler, da wir die letzte Klasse erweitern

Kompilierungsfehler(b)


abstract final class OmaenanishitekuretennoHoge { } //abstrakt und endgültig!?Also Fehler kompilieren

strictfp strenge FP (Floating Poing). Das ist ein strikter Gleitkommawert. was ist das? Ich bin nicht gut in Mathe. Wenn ich es also grob aufrunde, wird die Behandlung des Dezimalpunkts vom IEEE festgelegt, aber in der Welt von strictfp ist float float und double ist double, einschließlich Zwischenwerten. Es scheint, dass es als (keine implizite Typkonvertierung) behandelt wird, aber es erlaubt in gewissem Maße Rundungsfehler (Unterlauf) und Ziffernverlust (Überlauf) in einem Kontext, der nicht streng ist (Referenz). /javase/specs/jls/se8/html/jls-15.html#jls-15.4)). Anscheinend gibt es eine Funktion, um den Unterschied im Ergebnis aufgrund des Unterschieds in der Anzahl der effektiven Ziffern des Gleitkommas zwischen 32-Bit- und 64-Bit-Berechnung zu beseitigen. .. .. Ich bin mir nicht sicher, weil ich es nicht gesehen habe.

Erbe

Durch die Erweiterung der Klasse wird Folgendes geerbt.

Eine mehrfache gleichzeitige Vererbung ist in Java nicht möglich. Es scheint, dass es C ++ genannt werden kann.

ist eine Beziehung und hat eine Beziehung

Wenn B A erweitert, ist es nur B "ist-a". In Java sind alle Klassen Objektklassen, da die Eltern aller Klassen Objekte sind. has-a bedeutet nur, dass eine Klasse eine andere als Instanzvariable enthält. Es gibt zwei weitere Typen, und im Fall der "Aggregation" teilen sich die zugehörigen Objekte keinen Lebenszyklus. Im Fall von "Zusammensetzung" wird der Lebenszyklus geteilt (kurz gesagt, wenn B a hat, wenn B zerstört wird, wird auch a zerstört).

aggregation


package net.mognet.java8gold;
class A {
	public A() {
		System.out.println("A is created.");
	}
	@Override
	protected void finalize() throws Throwable {
		System.out.println("A is finalized.");
	}
}
class B {
	private A a;
    public B(A a) {
    		this.a = a;
    		System.out.println("B is created.");
    }
    
    @Override
    protected void finalize() throws Throwable {
    		System.out.println("B is finalyzed.");
    }
}
public class Test {
	public static void main(String[] args) throws InterruptedException {
		A a = new A();
		B b = new B(a);
		b = null;
		System.gc();  //b ist finalisiert, aber a ist nicht finalisiert
	}
}

composition


class A {
	public A() {
		System.out.println("A is created.");
	}
	@Override
	protected void finalize() throws Throwable {
		System.out.println("A is finalized.");
	}
}
class B {
    A a = new A();
    public B() {
    		System.out.println("B is created.");
    }
    
    @Override
    protected void finalize() throws Throwable {
    		System.out.println("B is finalyzed.");
    }
}
public class Test {
	public static void main(String[] args) throws InterruptedException {
		B b = new B();
		b = null;
		System.gc();   //Jetzt sind sowohl A als auch B finalisiert
	}
}

Polymorphismus

Grob gesagt können Sie ein untergeordnetes Objekt mit dem übergeordneten Typ erstellen.

class A {}
class B extends A {}
class C {
    private A a = new B(); //OK
}

Im Extremfall sind alle Oberklassen Objekte. Tun Sie dies auch.

class A {}
class B extends A {}
class C extends B {}
class Test {
    private Object a = new A(); //OK
    private Object b = new B(); //OK
    private Object c = new C(); //OK
}

Selbst wenn Sie den spezifischen Typ zur Kompilierungszeit nicht kennen, können Sie, wenn Sie die allgemeine Methode kennen, die bereitgestellt werden soll, diese zum Typ der übergeordneten Klasse machen und den Code zum Aufrufen dieser Methode schreiben. Das tatsächliche Verhalten (Methodenimplementierung) wird zur Laufzeit ermittelt.

Methode der Objektklasse

Methode Inhalt
boolean equals(Object obj) Gibt zurück, ob das Objekt und das übergebene Objekt gleich sind
protected void finalize() Wird beim Ausführen von gc aufgerufen
Class<?> getClass() Gibt eine Laufzeitklasse zurück
int hashCode() Gibt den Hashwert des Objekts zurück
void notify() 1 Thread fortsetzen
void notifyAll() Setzen Sie alle Threads fort
String toString() Gibt das Objekt als Zeichenfolge zurück
void wait() notify()Warte bis

statische Jungs

static fields Es gibt nur eine statische Variable physisch (im Speicher), egal wie viele Instanzen sie hat.

staticFields


class A {
    private static int i = 0;
    public static void add(int a) { i = i + a; }
    public static int getI() { return i; }
} 
public class Test {
	public static void main(String[] args) {
		A[] a = { new A(), new A(), new A(), new A() }; //Egal wie viele Instanzen Sie erstellen
		a[0].add(3);
		System.out.println(a[1].getI());  //3 kehrt zurück
		a[2].add(4);
		System.out.println(a[3].getI());  //7 kehrt zurück
	}
}

Nur statische Personen können auf statische Felder zugreifen. Tun Sie dies auch dann nicht, wenn Sie einen Fehler machen (Kompilierungsfehler (a)).

Kompilierungsfehler(a)


class A {
    private static int i;
    public A(int i) {
        this.i = i;    //nicht im statischen Feld-Kompilierungsfehler mit statischem Zugriff
    }
}

Da es auch als Alias- oder Klassenvariable bezeichnet wird, handelt es sich nicht um eine Instanzvariable, sodass nicht wie auf "this.i" darauf zugegriffen werden kann. Vielmehr kann es ohne Instanziierung verwendet werden.

staticFields2


class A {
    private static int i = 0;
    public static void add(int a) { i = i + a; }
    public static int getI() { return i; }
} 
public class Test {
	public static void main(String[] args) {
		System.out.println(A.getI());  //0 wird zurückgegeben
	}
}

static methods Alias-Klassenmethode. Wenn Sie Schlüsselwörter wie dieses oder super verwenden, die Instanzen sein sollen, wird ein Kompilierungsfehler angezeigt (a). Das Gegenteil ist natürlich in Ordnung.

Kompilierungsfehler(a)


class A {
    private static int i = 0;
    private int memberField = 0;
    public void memberMethod() { //do something with i } //OK
    public static void classMethod() { //do something with this.memberField } //Kompilierungsfehler, da auf die Mitgliedsvariable von der statischen Methode verwiesen wird
}

static initializer Code, der ausgeführt wird, wenn die Klasse geladen wird, dh wenn die JVM gestartet wird. Es kann hauptsächlich zum Initialisieren statischer Felder verwendet werden, kann aber auch das Schreibverhalten beeinflussen. Kompilierungsfehler (a), wenn Sie auf ein Feld zugreifen, das außerhalb des Blocks des statischen Initialisierers deklariert ist, oder wenn Sie dieses oder super verwenden, was im statischen Kontext zulässig ist.

Kompilierungsfehler(a)


clss A() {
    private int i;
    private static int j;
    static {
        this.i = 1;    //Kompilierungsfehler, weil Sie auf eine Instanzvariable zugreifen
        j = 1;         //OK
        static int k = 1;  //Kompilierungsfehler (schwierig!) Da im statischen Initialisierer statisch hinzugefügt wird.
    }
}

Singleton-Muster

Ein Entwurfsmuster, das auf der Garantie basiert, dass es nur eine Instanz einer Klasse gibt.

Singleton


public class SingletonHoge {
    private static SingletonHoge shoge = new SingletonHoge();
    private SingletonHoge() {}
    public static SingletonHoge getInstance() { return shoge; }
}

Unveränderliche Klasse

Eine Klasse, die so konzipiert ist, dass der Inhalt (Felder) eines Objekts nach der Instanziierung nicht aktualisiert wird.

Immutable


public final class ImmutableHoge {
    private final int hoge;
    private final int[] hogearray = { 1, 2, 3 };
    public ImmutableHoge(int hoge) { this.hoge = hoge; }
    public int getHoge() { return this.hoge; }
    public ImmutableHoge add(int hoge) { new ImmutableHoge(this.hoge + hoge); }
}

abstract, static, and default methods Ab Java 8 können Sie Implementierungsmethoden in die Schnittstelle schreiben.

Interface


interface Hoge {
    void doHoge(); //abstract
    static void staticDoHoge() {
        //do something in static context
    }
    default void defaultDoHoge() {
        //do something
    }
}

Die statische Methode einer Schnittstelle kann jedoch nur von einem Verweis auf die Schnittstelle aufgerufen werden.

staticMethod


interface InterfaceHoge {
    static void doHoge() { System.out.println("hoge"); }
}
class ClassHoge implements InterfaceHoge {
    ClassHoge choge = new ClassHoge();
    InterfaceHoge.doHoge();    //OK
    choge.doHoge();            //Kompilierungsfehler, da er von der Instanz der Implementierungsklasse aufgerufen wird
    ClassHoge.doHoge();        //Kompilierungsfehler, da er von einem Verweis auf die Implementierungsklasse aufgerufen wird
}

Verschachtelte Klasse

Eine innerhalb eines Blocks deklarierte Klasse.

  1. Verschachtelte Klasse von Klassenmitgliedern (Innere Klasse)
  1. statische Mitgliedsklasse: Eine verschachtelte Klasse, die als Klassenmitglied als statisch deklariert wurde

Beachten Sie, dass alle Elementklassen in der Schnittstelle als statisch behandelt werden, sodass sie nicht als innere Klassen behandelt werden (statische Elementklassen werden).

NestedClass


public class OuterHoge {
    static class InnerStaticHoge { }   //statische Mitgliedsklasse
    private class InnerPrivateHoge { } //Mitgliedsklasse (nicht statische Mitgliedsklasse)
    void doHoge() {
        class HogeInMethod { }         //Lokale Klasse
    }
}

So nennt man es.

public class OuterHoge {
    public void doHoge() {
        InnerHoge ih = new InnerHoge();
        ih.doInnerHoge();
    }
    public class InnerHoge {            //Mitgliederklasse
        public void doInnerHoge() { }
    }
}

Das Aufrufen aus dem statischen Kontext ist verwirrend, aber nach dem Erstellen einer Instanz der Outer-Klasse neu aus dieser Objektreferenz.

public class OuterHoge {
    public static void doHoge() {
        OuterHoge oh = new OuterHoge();    //Instanziieren Sie sich (äußere Klasse)
        InnerHoge ih = oh.new InnerHoge(); //Neu aus einem Verweis auf die äußere Klasse
        ih.doInnerHoge();
        //InnerHoge ih = new OugerHoge().new InnerHoge(); //Wenn Sie es in eine Zeile setzen, wird es so sein
    }
    public class InnerHoge {
        public void doInnerHoge() { }
    }
}

Anrufe aus anderen Klassen.

public class AnotherHoge {
    public void doAnotherHoge() {
        OuterHoge oh = new OuterHoge();
        OuterHoge.InnerHoge ih = oh.new InnerHoge();
        ih.doInnerHoge();
    }
}

Anonyme Klasse (https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.9.5)

Wird vom Compiler automatisch erstellt, wenn die Klasse instanziiert wird. Anonyme Klassen sind nicht abstrakt, implizit endgültig und immer nicht statische innere Klassen. Wird tatsächlich verwendet, um eine Implementierung der Schnittstelle bereitzustellen (das heißt, es ist jetzt nicht mehr erforderlich, dass die Standardmethode für die Schnittstelle definiert werden kann? Ich frage mich, ob sie tatsächlich in verschiedenen Light-Implementierungen an verschiedenen Stellen verwendet wird. verwenden).

interface Hoge {
    public void doHoge(); //abstrakte Methode
}
class HogeClass {
	void hogeMain() {
            Hoge hoge = new Hoge() {
        	@Override
        	public void doHoge() { }
        };
        hoge.doHoge();
	}
}

Der Punkt ist, dass Sie eine Methode implementieren können, indem Sie vor Ort ein Objekt vom Typ Schnittstelle erstellen und eine anonyme Klasse darin erstellen, ohne eine Klasse erstellen zu müssen, die die Schnittstelle implementiert und die Methode überschreibt.

Wenn Sie mit einem Liner schreiben, wird es so sein.

new Hoge() {
    public void doHoge() {}
}.doHoge();

Ich frage mich, ob es zu diesem Punkt kommt. .. .. Als ich mir die DataSource-Eigenschaft von MySQL ansah, als ich den Quellcode des Treibers las, erinnere ich mich, dass die innere Klasse überall auftauchte und ich war verwirrt darüber, was ich aufrufen und wie ich sie aufrufen sollte, aber nur, indem ich diesen Bereich beherrsche. vielleicht.

Aufzählungstyp

Wird verwendet, um verwandte Konstanten (implizit "public static final") zu einer zu kombinieren. Die Syntax lautet modifier enum Name {Const1, Const2, ...}.

public enum DogType {
    BORDER_COLLIE, GOLDEN_RETRIEVER, AKITA; //Wenn Sie andere Felder und Methoden deklarieren, schreiben Sie vorher Konstanten.
    private int hoge;        //Felder können auch deklariert werden
    public void doHoge() { } //Sie können auch Methoden deklarieren
}

Wie Klassen und Schnittstellen kann es als oberster oder verschachtelter Typ deklariert werden und wird implizit als "endgültige" Klasse kompiliert (nicht erweiterbar). Im Gegensatz zu verschachtelten Klassen kann es nicht innerhalb einer Methode deklariert werden. Alle Aufzählungstypen werden implizit als Unterklassen von java.lang.Enum kompiliert, so dass es nicht möglich ist, irgendetwas zu erweitern, aber es ist möglich, Schnittstellen zu implementieren. Verschachtelte Aufzählungstypen sind implizit "statisch" (können explizit sein). Eine Methode, die von der Klasse "java.lang.Enum" bereitgestellt wird.

`String final name()`
Gibt den Namen der Aufzählungskonstante als Zeichenfolge zurück
`int ordinal()`
Gibt die Reihenfolge der Aufzählungskonstanten zurück
`static > valueOf(Class type, String name)`
Gibt ein Aufzählungskonstantenobjekt zurück, das der Aufzählungskonstante mit dem im zweiten Argument angegebenen Namen aus dem im ersten Argument angegebenen Aufzählungstyp entspricht
`static E valueOf(String name)`
Gibt eine Aufzählungskonstante zurück, die der Aufzählungskonstante mit dem angegebenen Namen entspricht
`static E[] values()`
Gibt ein Array von Aufzählungstypen zurück

EnumTest


enum DogTypes {
	BORDER_COLLIE, BULL_DOG, GOLDEN_RETRIEVER;
	private int i = 0;
	public void printField() { System.out.println(i); }
}
public class EnumTest {
	public static void main(String[] args) {
		System.out.println(DogTypes.BORDER_COLLIE);
		for(DogTypes dt : DogTypes.values()) {
			dt.printField();
			System.out.println(dt + ": " + dt.name());
		}
		System.out.println(DogTypes.valueOf("BORDER_COLLIE"));
	}
}

Ausführungsergebnis


BORDER_COLLIE
0
BORDER_COLLIE: BORDER_COLLIE
0
BULL_DOG: BULL_DOG
0
GOLDEN_RETRIEVER: GOLDEN_RETRIEVER
BORDER_COLLIE

Konstrukteur

Nur private Konstruktoren sind erlaubt. Ein Argument ist nicht möglich. Da es erforderlich ist, dass es sich um ein einzelnes und unveränderliches Objekt handelt, geben Sie beim Erstellen des Objekts den Feldwert an (Setter wird nicht bereitgestellt, nur Getter).

enum DogTypes {
    NA, SMALL(5), MEDIUM(10), LARGE(20);      //Argumentloser Konstruktor mit jeweils 5 Argumenten, 10,Zum Aufrufen von 20 Konstruktoren
    private int weight;
    private DogTypes() { this.weight = 1; }
    private DogTypes(int weight) { this.weight = weight; }
    public int getWeight() { return this.weight: }
}
class Hoge {
    public void doHoge() {
        DogTypes dt = DogTypes.MEDIUM;
        System.out.println(dt.getWeight());
    }
}

Bis hierher für diese Zeit.

Recommended Posts

Infrastructure Shop wird Java erneut studieren (1. Klasse)
Java- und Swift-Vergleich (3) Klassenimplementierung / Klassenvererbung / Klassendesign
Java-Klassenmethoden
[Java] Klassenvererbung
Lassen Sie uns Java studieren
Java-Scanner-Klasse
Java HashMap-Klasse
Java-Entwurfsmuster
Java (abstrakte Klasse)
[Java] Verschachtelte Klasse
Anonyme Java-Klasse
Java-Entwurfsmuster
Über die Java-Klasse
[Java] Studiennotizen
Java 8 studieren (wiederholbar)
Java-Studienmemorandum
[Java] Abstrakte Klasse
[Java] Objektklasse
Lokale Java-Klasse
Studieren Sie Java Silver 1