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.
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 | 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 |
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.
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.
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
}
}
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 | 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 |
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.
}
}
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; }
}
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
}
Eine innerhalb eines Blocks deklarierte Klasse.
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();
}
}
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.
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.
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
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