Lassen Sie uns über die vorübergehende Erfahrung von Java SE 8 Programmer II sprechen

Dieser Artikel ist der 22. Tagesartikel von Fujitsu Extended Advent Calendar 2016. Bitte beachten Sie, dass der folgende Inhalt nicht repräsentativ für das Unternehmen / die Organisation ist, zu dem Sie gehören, und meiner Meinung nach.

Auslösen

Sie müssen mindestens eine Qualifikation erwerben, die durch den Eintritt in das Unternehmen als neuer Absolvent (z. B. Prüfung zum Ingenieur für angewandte Informationstechnologie) und den Titel Java SE 8 Programmer II angegeben wurde. [Oracle] -Zertifizierung (https://www.oracle.com/index.html), die durch Bestehen von /pls/web_prod-plq-dad/db_pages.getpage?page_id=5001&get_params=p_exam_id:1Z0-809&p_org_id=70 erhalten werden kann) Qualifizierter ** Oracle Certified Java Programmer, Gold SE 8 ** (im Folgenden als Gold bezeichnet) und ein Rang unter [Java SE 8 Programmer I](http://education.oracle.com/pls/web_prod- Dazu gehört auch ** Oracle Certified Java Programmer, Silver SE 8 ** (im Folgenden als Silver bezeichnet), das durch Übergeben von plq-dad / db_pages.getpage? Page_id = 5001 & get_params = p_exam_id: 1Z0-808 & p_org_id = 70 erhalten werden kann. Ich werde. Eine Übersicht über von Oracle zertifizierte Java 8-Zertifizierungen finden Sie auch unter dieser URL, aber auch in der folgenden Tabelle. Ich habe versucht, es auf meine eigene Weise zusammenzufassen.

Name Voraussetzungen Qualifikationsprüfung Ziel
Java Programmer, Bronze SE 7/8 Keiner Java SE 7 / 8 Bronze Für Anfänger, die aus der Grundgrammatik verstehen können, wie z. B. ob Aussage zur Objektorientierung.
Java Programmer, Silver SE 8 Keiner Java SE 8 Programmer I Klassen wie Polymorphismus und Niedergeschlagenheit(Schnittstelle)Beziehungen undStringArrayListKlasse, Lambda-Ausdruck aus Java8, Datum/Für Entwickler, die die grundlegenden Spezifikationen von Standardmethoden wie die grundlegende Verwendung der Zeit-API verstehen.
Java Programmer, Gold SE 8 Java Programmer, Silver SE 8 Java SE 8 Programmer II Entwerfen unveränderlicher Objekte, Generika, innerer Klassen usw., Java I./O(NIO.Einschließlich 2 Systeme), Executor Framework usw. Für Experten, die detaillierte Grammatik und Design verstehen.
Das gleiche wie oben Java Programmer, Gold SE 7 Upgrade to Java SE 8 Programmer Das gleiche wie oben
Das gleiche wie oben Java Programmer(SE 6 oder früher) Upgrade to Java SE 8 OCP ( Java SE 6 and all prior versions) Das gleiche wie oben

Als Student hatte ich die Erfahrung, einfache Android-Anwendungen selbst mit Java zu entwickeln, und ich beschäftige mich bei meiner Arbeit häufig mit Java. Deshalb wollte ich frühzeitig die Qualifikationsnorm für Neulinge erreichen. Deshalb wollte ich Silber erwerben, was eine Voraussetzung für Gold ist. Infolgedessen habe ich Silver Anfang September dieses Jahres relativ leicht bestanden, was für die Selbstverbesserung nicht ausreichte. Daher möchte ich fortgeschrittenere Java-Grammatikkenntnisse und kürzlich (Java8, Java9) Java-Interface-Design studieren Um den Trend zu erfassen, habe ich mich für Gold entschieden, das schwieriger ist als Silber.

Inhalt der Frage

Offizielle URL von Oracle Es wird mit Notizen über beschrieben. In dieser Spalte werde ich die Bulletins der darin enthaltenen Themen zitieren und erläutern. Ich hoffe, dass diejenigen, die die Gold-Prüfung ablegen, auf diese Weise gefragt werden, und diejenigen, die die Prüfung nicht ablegen, das Gefühl haben, dass die neueste offizielle Java-API so ist. Darüber hinaus kann Gold nicht ohne den Erwerb von Silber erworben werden. Daher gehen wir natürlich davon aus, dass Sie den gesamten in der obigen Tabelle beschriebenen Fragenbereich in Silber verstehen.

Java-Klassendesign

  • Kapselung implementieren
  • Implementieren Sie die Vererbung einschließlich Zugriffsmodifikatoren und Kompositionen
  • Polymorphismus implementieren
  • Überschreiben Sie die Methoden hashCode, equals und toString der Objektklasse
  • Erstellen und verwenden Sie Singleton- und unveränderliche Klassen
  • Verwenden Sie das Schlüsselwort "static" in Initialisierungsblöcken, Variablen, Methoden und Klassen
  • Schreiben Sie Code, der abstrakte Klassen und Methoden verwendet
  • Schreiben Sie Code, der das Schlüsselwort final verwendet
  • Erstellen Sie innere Klassen wie statische innere Klassen, lokale Klassen, verschachtelte Klassen, anonyme innere Klassen usw.
  • Verwenden Sie Aufzählungstypen, einschließlich solcher, deren Methoden und Konstruktoren innerhalb von Aufzählungstypen liegen.
  • Schreiben Sie Code, der Schnittstellen deklariert, implementiert und erweitert. Verwenden Sie die Annotation "@ Override"
  • Erstellen und verwenden Sie Lambda-Ausdrücke

Es gibt viele Überschneidungen mit Silver, aber das Erstellen einer anonymen Klasse hängt stark mit der Funktionsschnittstelle und der Stream-API zusammen, die später angezeigt werden. Sie sollten sie daher gut verstehen. Ich erinnere mich auch, dass ich Probleme hatte, wie man eine vorhandene Klasse in eine unveränderliche Klasse umwandelt. Darüber hinaus muss dem Konstruktor im Aufzählungstyp ("Enum" -Klasse) ein privater Modifikator zugewiesen werden, der jedoch tatsächlich öffentlich ist. Daher lautet die richtige Antwort "Kompilierungsfehler in Zeile XX". Es gab auch ein Problem, dass Sie die richtige Antwort nur bemerken würden, wenn Sie die Details wie z. Mit Java 8 können Sie Standard- und konkrete statische Methoden in Ihrer Benutzeroberfläche definieren. Damit

interface A {
	void foo();
}

interface B extends A {
	@Override
	default void foo() {}
}

interface C extends A {
	@Override
	default void foo() {}
}

class D implements B, C {}

Sie können solche Diamanten erben. Natürlich führt die Zeile "Klasse D implementiert B, C {}" zu einem Kompilierungsfehler. Ebenfalls,

interface E {
	default void x(String s) {}
	static void y(String s) {}
	void z(String s);
}

Eine Schnittstellendefinition wie E e = s-> System.out.println (s); liegt daran, dass es sich um eine funktionale Schnittstelle handelt (default-Methode und konkrete static-Methode werden ignoriert). Sie können Lambda-Ausdrücke schreiben. Ich denke, es gab ein Problem, das auf diesem Inhalt beruhte, sogar in der eigentlichen Prüfung. Übrigens haben sich die Kompilierungsspezifikationen lokaler und anonymer Klassen zwischen Java 7 und Java 8 geändert.

class Outer {
	private static String a = "A";

	public static void main(String[] args) {
		Outer q = new Outer();
		q.foo("B");
	}

	public static void foo(String b) {	//Gewähren Sie der Variablen b aus Java 8 implizit den endgültigen Modifikator
		String c = "C";					//Implizites Zuweisen des endgültigen Modifikators zur Variablen c aus Java 8
		Inner inner = new Inner(){
			@Override
			public void bar(String d) {
				System.out.println(a + b + c + d);
			}
		};
		//b = "BB";
		//c = "CC";
		inner.bar("D");
	}

	interface Inner {
		public void bar(String d);
	}
}

Wenn ich mit dem Compiler der Version 1.7 kompiliere, erhalte ich einen Kompilierungsfehler, dass die lokalen Variablen "b" und "c" als "final" deklariert werden müssen, aber in Version 1.8 wird die Kompilierung bestanden. Dies liegt daran, dass Java 8 zu einer Spezifikation geworden ist, die den lokalen Variablen "b" und "c" zur Kompilierungszeit implizit das Qualifikationsmerkmal "final" hinzufügt. Hintergrund ist die Einführung des später beschriebenen Lambda-Ausdrucks. Ich denke, das lag daran, dass ich wollte, dass es natürlich aussieht, als würde ich eine anonyme Klasse als Funktion bestehen. Es ist jedoch NG, "b =" BB "" und "c =" CC "zu kommentieren, da die lokalen Variablen" b "und" c "implizit den" endgültigen "Modifikator erhalten. Ein Kompilierungsfehler tritt auf, unabhängig davon, ob die Version von "javac" 1.7 oder 1.8 ist. Übrigens, wenn der obige Quellcode kompiliert und ausgeführt wird, wird "ABCD" ausgegeben.

Generika, Sammlung

  • Generische Klassen erstellen und verwenden
  • Erstellen und verwenden Sie die Objekte ArrayList, TreeSet, TreeMap und ArrayDeque
  • Verwenden Sie die Schnittstellen java.util.Comparator und java.lang.Comparable

In Java sind Arrays kovariant, aber ich erinnere mich, dass ich Probleme damit hatte, dass Generika unveränderlich sind. Mit anderen Worten

Number[] array = new Integer[3];

Wird kompilieren, aber

ArrayList<Number> list = new ArrayList<Integer>(3);

Führt zu einem Kompilierungsfehler. Es gab auch einen Platzhalter und einen Grenz-Platzhalter. Zum Beispiel

ArrayList<?> list = new ArrayList<Integer>();

Wird kompilieren, aber

ArrayList<Integer> list = new ArrayList<?>();
ArrayList<?> list = new ArrayList<?>();

Führt in beiden Zeilen zu einem Kompilierungsfehler. Dies liegt daran, dass auf der rechten Seite von = keine Platzhalter verwendet werden sollten. Ebenfalls,

ArrayList<? extends Number> list = new ArrayList<Integer>();

Wird kompilieren, und für diese Angelegenheit

List<? super Integer> list = new ArrayList<Number>();

Wird auch kompilieren. Es wird empfohlen, dass Sie die Spezifikationen der Schnittstellen "java.lang.Comparable" und "java.util.Comparator" vollständig verstehen. In dieser Hinsicht muss die Schlüsselklasse, die Sie der Instanz "java.util.TreeMap" hinzufügen, die Schnittstelle "java.lang.Comparable" implementieren. Wenn Sie sie jedoch nicht "implementieren", wird sie zur Laufzeit "implementiert". Eine lava.lang.ClassCastException` wird ausgelöst (beachten Sie, dass dies kein Kompilierungsfehler ist). Übrigens wurden keine Fragen zu "Deque" gestellt. Vielleicht ist es nur eine Laune.

Lambda integrierte Funktionsschnittstelle

  • Verwenden Sie die im Paket "java.util.function" enthaltenen integrierten Schnittstellen, z. B. "Prädikat", "Verbraucher", "Funktion", "Lieferant"
  • Verwenden Sie eine Funktionsschnittstelle, die primitive Typen verarbeitet
  • Verwenden Sie eine Funktionsschnittstelle mit zwei Argumenten
  • Schreiben Sie Code, der die 'UnaryOperator'-Schnittstelle verwendet

Da es sich um eine notwendige Beschreibung für die später beschriebene Stream-API handelt, war es meines Erachtens das Feld mit der zweitgrößten Anzahl von Fragen **. Denken Sie unbedingt an die folgenden vier Schnittstellennamen, die ich persönlich ** Four Tenno ** nenne, und deren abstrakte Methodennamen. Wenn Sie sich an mindestens diese vier erinnern, Schnittstellen mit Bi wie BiConsumer <T, U> und primitiven Typen (int, long, double, boolean) Sie müssen sich nicht an die Schnittstellen wie "DoublePredicate" und "LongToDoubleFunction" erinnern, auf die Sie sich spezialisiert haben.

Name der Schnittstelle Name der abstrakten Methode Bemerkungen
Function<T, R> R apply(T t) Vier TennoEiner von
Consumer<T> void accept(T t) Vier TennoEiner von
Supplier<T> T get() Vier TennoEiner von
Predicate<T> boolean test(T t) Vier TennoNur einer von ihnen, dieser Typ wird in Silber gefragt
BiFunction<T, U, R> R apply(T t, U u) -
UnaryOperator<T> T apply(T t) Function<T, T>Subschnittstelle von
BinaryOperator<T> T apply(T t1, T t2) BiFunction<T, T, T>Subschnittstelle von
IntFunction<R> R apply(int value) -
ToDoubleFunction<T> double applyAsDouble(T t) double apply(T t)ist nicht
IntToDoubleFunction double applyAsDouble(int value) double apply(T t)ist nicht
IntConsumer<T> void accept(int value) -
IntSupplier<T> int getAsInt() int get()ist nicht
IntPredicate<T> boolean test(int value) -

Wichtiger als dieses Wissen ist es natürlich, dass Sie einen Lambda-Ausdruck (oder die später beschriebene Methode) über eine funktionale Schnittstelle zuordnen können. Umgekehrt können Sie jedoch einen Lambda-Ausdruck mit der von Ihnen verwendeten funktionalen Schnittstelle verknüpfen. Ist zu sein. Wenn es sich beispielsweise um eine "Supplier " - Schnittstelle handelt, können Sie den Typ "String" vom Typ "void" zurückgeben.

Supplier<String> a = () -> "HelloWorld!"

In der Lage sein, Lambda-Ausdrücke wie zu definieren

b = s -> s.concat("World!")

Sie müssen sich nur den Lambda-Ausdruck in ansehen und den Variablentyp der Variablen b mit Function <String, String> oderUnaryOperator <String>verknüpfen. Außerdem ist es wichtig zu verknüpfen, wie abstrakte Methoden verwendet werden sollten, um eine funktionale Schnittstelle tatsächlich anzuwenden. Wenn Sie den Lambda-Ausdruck im vorherigen Beispiel verwenden möchten, um den String "HelloWorld!" Der Typvariablen "String" zuzuweisen, dann ist "String str = a.get ();" oder "String str = b". Sie können anwenden schreiben ("Hallo"); `. Weiteres Anwenden des obigen Wissens

DoubleFunction<BiConsumer<Integer, Double>> func = x -> (y, z) -> System.out.println(x / z + y);

Es gab auch einen verschachtelten Lambda-Ausdruck wie. Wenn Sie das Berechnungsergebnis von 5.0 / 2.0 + 3 = 5.5 ausgeben möchten, schreiben Sie func.apply (5.0) .accept (3, 2.0);.

Java Stream API

  • Beschreiben von Stream-Schnittstellen und Pipelines
  • Filtern Sie Sammlungen mit Lambda-Ausdrücken
  • Verwenden Sie Methodenreferenzen mit Streams
  • Extrahieren Sie Daten aus einem Objekt mit den Methoden peek () und map (), einschließlich der Basisversion der Methode map ()
  • Suchen Sie Daten mit Suchmethoden wie "findFirst", "findAny", "anyMatch", "allMatch", "noneMatch"
  • Verwenden Sie die Klasse "Optional"
  • Schreiben Sie Code, der die Daten und Berechnungsmethoden des Streams verwendet
  • Sammlungen mit der Stream-API sortieren
  • Verwenden Sie die Methode collect (), um die Ergebnisse in einer Sammlung zu speichern. Gruppen- / Partitionsdaten mit der Klasse "Collectors"
  • Verwenden Sie die Methode flatMap ()

Zum Teil, weil es das Hauptmerkmal von Java8 ist, ** ist die Anzahl der Fragen sehr groß, und ich denke, dass ungefähr 50% der Probleme tatsächlich mit der Stream-API zusammenhängen **. Ich denke, alle Spalten, die ich in den obigen Bulletins geschrieben habe, sind wichtig. Stream verwendet die Schnittstelle "Stream " und die Schnittstelle "IntStream", die auf ihren primitiven Typ spezialisiert ist, und arbeitet gemäß dem folgenden Ablauf.

  1. Generieren Sie einen Stream, der mehrere Elemente aus jedem Element eines Arrays, einer Sammlung usw. enthalten kann. (Sie können den zu haltenden Wert auch direkt angeben.)
  2. Nehmen Sie einige Änderungen an den Werten vor, die der Stream während des Mappings, Filterns, Debuggens usw. enthält (= Zwischenoperation).
  3. Gibt ein Ergebnis aus dem vom Stream gehaltenen Wert zurück (= Beendigungsoperation)

Beachten Sie jedoch die folgenden Punkte. Dieser Inhalt sollte auch im Zusammenhang mit der eigentlichen Prüfung beachtet werden.

Der größte Vorteil der Stream-API besteht darin, dass Sie 1 bis 3 Aktionen in einer Zeile ** codieren können. Dies soll die Lesbarkeit des Codes verbessern und Fehler sofort finden. Angenommen, Sie möchten Java-Code schreiben, der alle Geschwister- und untergeordneten Dateien / Verzeichnisse aus dem aktuellen Verzeichnis mit NIO.2 aus Java 7 ausgibt, das später beschrieben wird. Zu diesem Zeitpunkt war es in javac Version 1.7 erforderlich, eine lange Anzahl von Zeilen zu codieren, indem die vier abstrakten Methoden der FileVisitor-Schnittstelle wie unten gezeigt überschrieben wurden.

import java.io.IOException;

import java.nio.file.Files;
import java.nio.file.FileVisitOption;
import java.nio.file.FileVisitResult;
import java.nio.file.FileVisitor;
import java.nio.file.Path;
import java.nio.file.Paths;

import java.nio.file.attribute.BasicFileAttributes;

class Search7 {
	public static void main(String[] srgs) {
		try {
			Files.walkFileTree(
					Paths.get("./"),
					new FileVisitor<Path>() {
						@Override
						public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
							System.out.println(dir);
							return FileVisitResult.CONTINUE;
						}

						@Override
						public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
							System.out.println(file);
							return FileVisitResult.CONTINUE;
						}

						@Override
						public FileVisitResult visitFileFailed(Path file, IOException exc) {
							return FileVisitResult.CONTINUE;
						}

						@Override
						public FileVisitResult postVisitDirectory(Path dir, IOException exc) {
							return FileVisitResult.CONTINUE;
						}
					});
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

Andererseits erfordert Version 1.8 nur ** sehr kurze Zeilenanzahl **, wie unten gezeigt.

import java.io.IOException;

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

class Search8 {
	public static void main(String[] srgs) {
		try {
			Files.walk(Paths.get("./")).forEach(System.out::println);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

Beachten Sie, dass "System.out :: println" im Java 8-Code eine aus Java 8 hinzugefügte Notation ist und als Methodenreferenz bezeichnet wird. Diese Notation hat dieselbe Bedeutung wie der Lambda-Ausdruck "(Pfadpfad) -> System.out.println (Pfad)" und kann noch kürzer als der Lambda-Ausdruck geschrieben werden. Bitte beachten Sie, dass es im eigentlichen Test einige Fragen zur Funktionsschnittstelle gab. Zum Beispiel

ToDoubleFunction<String> ds = str -> Double.parseDouble(str);

Kann wie folgt umgeschrieben werden.

ToDoublefunction<String> = Double::parseDouble;

Aus der Beschreibung des Lambda-Ausdrucks geht hervor, dass Sie sich gut vorstellen können, wie die Methodenreferenz beschrieben werden soll und umgekehrt. Kehren wir nun zur Erklärung der Stream-API zurück, aber als Testvorbereitung werde ich die obigen Punkte 1 bis 3 erläutern. Schauen Sie sich zunächst den Code mithilfe der folgenden Stream-API an.

Stream<String> stream1 = Arrays.asList("a", "bb", "ccc", "dddd").stream();	//Stream-Generierung
Stream<Integer> stream2 = stream1.map(str -> str.length());					//Zwischenbetrieb Teil 1
Stream<Integer> stream3 = stream2.filter(num -> num > 1);					//Zwischenbetrieb Teil 2
Optional<Integer> result = stream3.max((num1, num2) -> num1 - num2);		//Kündigungsoperation
result.ifPresent(max -> System.out.println(max));

Die Stream-Generierungsfunktion in der ersten Zeile ist eine Instanz des Streams mit dem Typparameter T``stream1 vonstream (), der als Standard-Methode in derCollection <T>-Schnittstelle in Java 8 neu hinzugefügt wurde. Wird generiert. Da die Methode "Arrays.asList ()" die Schnittstelle "List " zurückgibt, die eine Unterschnittstelle der Schnittstelle "Collection " ist, gab es viele Fragen zum Erstellen von Streams mit dieser Methode. Die Zwischenoperation "map ()" in der zweiten Zeile ist ein Lambda-Ausdruck zum Aufrufen von "length ()" der "String" -Klasse für jedes der vier Elemente des "String" -Typs, die in "stream1" enthalten sind. Es ist angegeben. Infolgedessen werden die vier Elemente vom Typ "String" in den Typ "Integer" konvertiert, bei dem es sich um eine Wrapper-Klasse vom Typ "int" handelt, bei der es sich um den Rückgabewert von "length ()" handelt. Daher sind die von "stream2" gehaltenen Werte, die von "map ()" erzeugt werden, "1, 2, 3, 4". Beachten Sie, dass primitive Typen wie "int" in Generika nicht beschrieben werden können (ein Kompilierungsfehler tritt auf). Außerdem werden in der zweiten Zwischenoperation "filter ()" in der dritten Zeile die von "stream2" gehaltenen Werte "1, 2, 3, 4" gefiltert, um die Anzahl der gehaltenen Werte zu verringern. tun. Die Filterspezifikation verwendet auch einen Lambda-Ausdruck, der in diesem Beispiel angibt, dass nur Elemente mit einem Wert größer als 1 beibehalten und der Rest verworfen werden. Daher sind die von "stream3" gehaltenen Werte "2, 3, 4". Schließlich die Beendigungsoperation "max ()", die das Maximum der von "stream3" gehaltenen Werte "2", "3" und "4" zurückgibt. Wenn Sie jedoch den Maximalwert finden, muss die Definition des Maximums im Argument von "max ()" angegeben werden. Dieses Argument ist vom Typ "java.util.Comparator " und der Lambda-Ausdruck "(num1, num2) -> num1 --num2", der seine abstrakte Methode "int compare (T num1, T num2)" darstellt Es ist angegeben. Durch diese Spezifikation wird der Maximalwert in natürlicher Reihenfolge berechnet, so dass der Durchfluss "4" zurückgeben soll. Eine Operation, bei der bestätigt wird, dass alle Elemente "2", "3" und "4" von der Beendigungsoperation auf diese Weise verwendet werden, wird als Reduktionsoperation bezeichnet. Im obigen Beispiel gibt max () jedoch ein Instanz-Ergebnis vom TypOptional <T>zurück. Die Klasse "Optional " ist eine Containerklasse, die das Ergebnis der Stream-Beendigungsoperation speichert, und selbst wenn das Ergebnis der Beendigungsoperation "null" ist, kann die "optionale " - Instanz "null" speichern. Zu diesem Zeitpunkt ist das größte Merkmal, dass die optionale -Instanz selbst nicht null wird. Wenn im obigen Beispiel "ifPresent (Consumer <? Super T> consumer)" der Klasse "Optional " in der letzten Zeile aufgerufen wird und ein anderer Wert als "null" gespeichert wird, wird dies durch ein Argument angegeben. Wenn der Lambda-Ausdruck von "Consumer" ausgeführt und "Null" gespeichert wird, wird nichts unternommen. Ich denke, Sie können das Design lesen, das ** das Risiko eliminiert, zur Laufzeit java.lang.NullPointerException auszulösen **. Da "4" in "result" gespeichert ist, befindet sich "4" in "max" des Lambda-Ausdrucks "max-> System.out.println (max)" vom Typ "Consumer ". Es wird so wie es ist angewendet und als "4" ausgegeben. Wenn Sie das obige Beispiel in eine Anweisung schreiben und alle Methodenreferenzen anwenden, lautet die Beschreibung wie folgt (das Ausführungsergebnis ist natürlich dasselbe).

Optional<Integer> result =
	 Arrays.asList("a", "bb", "ccc", "dddd").stream()	//Stream-Generierung
	.map(String::length)								//Zwischenbetrieb Teil 1
	.filter(num -> num > 1)								//Zwischenbetrieb Teil 2
	.max((num1, num2) -> num1 - num2);					//Kündigungsoperation
result.ifPresent(System.out::println);

Darüber hinaus gibt es viele Methoden zum Erstellen von Streams, Ausführen von Zwischenoperationen und Ausführen von Beendigungsoperationen. Ich werde es weglassen, weil es mühsam ist, Artikel mehr zu schreiben ~~, aber wenn Sie stark in der Stream-API [Offizielle API-Sammlung] sein wollen (https://docs.oracle.com/javase/jp/8/docs/api) (/java/util/stream/Stream.html) Bitte beziehen Sie sich darauf. In der eigentlichen Prüfung habe ich das Gefühl, dass alle 10 der 10 oben geschriebenen Kugeln gegeben wurden.

Ausnahmen, Behauptungen

  • Verwenden Sie die Anweisungen try-catch und throw
  • Verwenden Sie die Klauseln "catch", "multi-catch" und "finally" Verwenden Sie Autoclose-Ressourcen mit der Anweisung + try-with-resources
  • Erstellen Sie benutzerdefinierte Ausnahmen und automatisch schließbare Ressourcen
  • Testen Sie unveränderliche Mengen anhand von Aussagen

Try-with-Resource ist eine praktische Funktion, die aus Java 7 hinzugefügt wurde, aber selbst in der SE8 Gold-Prüfung gab es im Zusammenhang mit JDBC einige Fragen, die später beschrieben werden. Zu diesem Zeitpunkt müssen Sie vorsichtig sein, wenn die überschriebene Methode close () und die Klausel catch ausgeführt werden.

class Main {
	static class X implements AutoCloseable {
		X() {
			System.out.println("X : Constructor");
		}

		@Override
		public void close() {
			System.out.println("X : close()");
		}
	}

	static class Y implements AutoCloseable {
		Y() {
			System.out.println("Y : Constructor");
		}

		@Override
		public void close() {
			System.out.println("Y : close()");
		}
	}

	public static void main(String[] args) {
		try (X x = new X();
			 Y y = new Y()) {
			throw new Exception("Exception");
		} catch (Exception e) {
			System.out.println(e.getMessage());
		} finally {
			System.out.println("finally");
		}
	}
}

Wenn die obige Quelldatei kompiliert und ausgeführt wird

X : Constructor
Y : Constructor
Y : close()
X : close()
Exception
finally

Wird ausgegeben. Obwohl die Variable "y" nach der Variablen "x" definiert ist, ist es leicht, abgefangen zu werden, ohne die Try-with-Resource-Spezifikation zu kennen, die die Methode "close ()" in umgekehrter Reihenfolge aufruft. Es ist auch leicht zu missverstehen, dass "Exception" vor "Y: close ()" ausgegeben wird, da es durch die Ausführungsreihenfolge der "try" -Klausel → "catch" -Klausel → "finally" -Klausel gezogen wird. .. Wenn Sie sich an jedes der oben genannten Ergebnisse erinnern, können Sie verhindern, dass Sie erwischt oder missverstanden werden. Wenn Sie eine Methode überschreiben, die in einer Oberklasse als "löst eine Ausnahme" oder "wirft eine RuntimeException" definiert ist, gibt es außerdem eine Frage zum Festlegen von "Würfen" für eine Methode in einer Unterklasse. tat. Überraschenderweise gab es zwei Fragen im Zusammenhang mit Behauptungen. In diesem Bereich möchten Sie eine solide Score-Quelle erstellen, da Sie nur die Syntax des Schlüsselworts "assert" lernen müssen.

Datums- / Uhrzeit-API (Java SE 8)

  • Datums- und zeitbasierte Ereignisse, z. B. "LocalDate", "LocalTime", "LocalDateTime", "Instant", "Period" und "Duration", um Datum und Uhrzeit in einem einzigen Objekt zu kombinieren. Erstellen und verwalten
  • Datum und Uhrzeit in mehreren Zeitzonen bearbeiten. Verwalten Sie Änderungen aufgrund der Sommerzeit, z. B. Formatieren von Datums- und Zeitwerten
  • Verwenden Sie "Instant", "Period", "Duration" und "TemporalUnit", um datums- und zeitbasierte Ereignisse zu definieren, zu erstellen und zu verwalten

Es ist eine andere API als die in Java8 neu implementierte Stream-API, aber ich denke, es wurde nicht viel gefragt. Ich glaube, ich habe keine Probleme mit den Klassen "ZonedDateTime", "Instant", Datums- / Zeitformaten und Sommerzeit gesehen, die Zoneninformationen enthalten ... Wie bei Silver wurde jedoch auch bei Gold nach dem Hakenproblem gefragt, bei dem es sich bei der LocalXXX-Klasse um eine unveränderliche Klasse handelt. Abgesehen davon ist "Periode" das Datum, "Dauer" das Zeitintervall, und ich bin der Meinung, dass es ausreicht, sich an die ISO 8601-Notation der Zeit zu erinnern. Wenn der einzige Zweck darin besteht, Gold, Silber + α zu erwerben Ich denke das ist genug. Außerdem hatten die Klassen "Date" und "Calendar" im alten Paket "java.util" keine Fragen. Wird es irgendwann "@ veraltet", wenn die Datums- / Zeit-API der zu SE 8 hinzugefügten API zum Mainstream wird?

Java I/O、NIO.2

  • Daten in die Konsole lesen / schreiben
  • Verwenden Sie "BufferedReader", "BufferedWriter", "File", "FileReader", "FileWriter", "FileInputStream", "FileOutputStream", "ObjectOutputStream", "ObjectInputStream" und "PrintWriter" im Paket "java.io" Machen
  • Bearbeiten Sie Datei- und Verzeichnispfade über die Schnittstelle "Pfad"
  • Verwenden Sie die Stream-API mit NIO.2.

Trotz der Tatsache, dass es viele Probleme gibt, die ohne Kenntnis der Methodenspezifikationen nicht gelöst werden können, ist die Anzahl der Fragen in der Prüfung unerwartet angemessen. Es war das Feld, in dem ich zu dieser Zeit nicht gut war, also bewegte ich meine Hand tatsächlich, während ich mir die [offizielle API-Sammlung] ansah (https://docs.oracle.com/javase/jp/8/docs/api/). Es ist am besten zu verstehen, während Sie das Testmuster implementieren. Ich denke, dass NIO.2 mehr Fragen hatte als der Eingabe- / Ausgabestream, der lange Zeit existierte, als NIO.2, das in Java 7 hinzugefügt wurde (beachten Sie, dass es sich vollständig von der in Java 8 hinzugefügten Stream-API unterscheidet). Ich werde. Zunächst der frühere Eingabe- / Ausgabestream, wenn eine "BufferedReader" -Instanz für eine bestimmte Datei erstellt wird, "read ()", "readLine ()", "mark ()" aus der in die Datei geschriebenen Zeichenfolge. Es gab tatsächlich ein Problem mit der Ausgabe mit , reset () und skip ()`. Hier ist eine kurze Zusammenfassung der Unterschiede zwischen "read ()" und "readLine ()" in der folgenden Tabelle.

Methodenname Leseeinheit Rückgabetyp Am Ende der Datei
read() Ein Charakter int(Normal,charExplizit in ein Zeichen umwandeln) -1Gib es zurück
readLine() 1 Zeile String(Der Zeilenvorschubcode wird automatisch erkannt und ist nicht im Rückgabewert enthalten.) nullGib es zurück

Hier lässt BufferedReader die Reader-Schnittstelle implementieren und deklariertmark (),reset ()usw. in dieser Schnittstelle, aber alle Implementierungsklassen von Reader unterstützen Operationen. Nicht immer. Wenn Sie diese mit einer nicht unterstützten Implementierungsklasse "Reader" ausführen, wird zur Laufzeit eine "java.io.IOException" ausgelöst. Dieser Unterstützungsstatus kann durch den Rückgabewert (boolean Typ) von markSupported () bestimmt werden. Ich erinnere mich nicht an den Fragenstatus anderer Eingabe- / Ausgabestreams als "BufferReader", aber zumindest denke ich, dass die Schnittstelle "java.io.Serializable" und "ObjectOutputStream" nicht gefragt wurden. Für Konsolen-Eingabe / Ausgabe-Beziehungen können Sie auch die Variable "System.in" vom Typ "InputStream" und die Variable "System.out" vom Typ "OutputStream" verwenden, jedoch die von Java 6 hinzugefügte "java.io.Console" Sie können auch die Klasse `verwenden. Ich denke, die Punkte dieser Klasse sind die folgenden zwei.

Ich denke, das verbleibende NIO.2 ist ziemlich wichtig. NIO.2 wird im Paket nach "java.nio" gespeichert und implementiert eine Funktion, mit der Datei- / Verzeichnisinformationen bearbeitet werden können, die von Eingabe- / Ausgabestreams nicht realisiert werden können. Im eigentlichen Test wird nur die statische Methode bereitgestellt, mit der sie ausgeführt werden. Kopieren (Option Pfad von, Pfad zu, CopyOption ...), Verschieben (Pfad von, Pfad zu, CopyOption) der Klasse "Dateien". ... Option) wird einzeln angegeben, und es ist erforderlich, auf die Ausführungsergebnisse wie LinkOption.NOFOLLOW_LINKS und StandardCopyOption.REPLACE_EXISTING` zu achten, die Optionen als Argumente variabler Länge nach dem dritten Argument angeben können. .. Darüber hinaus gibt es "readAllLines (Pfadpfad)" und "Zeilen (Pfadpfad)" als Methoden, mit denen alle Sätze in der Datei zeilenweise gelesen werden können. Die folgende Tabelle fasst die Unterschiede zwischen ihnen kurz zusammen.

Methodenname Rückgabetyp Eingeführte Version
static readAllLines(Path path) throws IOException List<String> Java7
static lines(Path path) throws IOException Stream<String> Java8

Die "Path" -Schnittstelle wird übrigens im Argument der Methoden dieser "Files" -Klassen angegeben. Es gab nur ein paar Fragen zu dieser "Pfad" -Schnittstelle. Natürlich gibt es keinen Konstruktor in der "Pfad" -Schnittstelle, und Instanzen können auf die folgenden zwei Arten erstellt werden.

Beachten Sie, dass der im Schnittstellenargument Path angegebene absolute / relative Pfad nicht das 0. Stammverzeichnis darstellt, sondern das Verzeichnis / die Datei, das dem Stammverzeichnis am nächsten liegt. Zum Beispiel

Path path = Paths.get("/usr/bin/java");
System.out.println(path.getName(0));
System.out.println(path.subpath(1, 3));

Erzeugt die folgende Ausgabe.

usr
bin/java

Außerdem sollten Sie auf den Unterschied im Verhalten achten, wenn resolve () undnormalize ()für das Path-Objekt mit relativem Pfad und absolutem Pfad ausgeführt werden.

Java-Parallelität

  • Erstellen Sie einen Worker-Thread mit "Runnable" und "Callable". Führen Sie Aufgaben gleichzeitig mit "ExecutorService" aus
  • Identifizieren Sie potenzielle Threading-Probleme wie Deadlock, Stabilisierung, Livelocking und Konfliktbedingungen
  • Verwenden Sie die Schlüsselwörter "synchronized" und "java.util.concurrent.atomic", um die Ausführungsreihenfolge des Threads zu steuern
  • Verwenden Sie Sammlungen und Klassen von java.util.concurrent, z. B. CyclicBarrier und CopyOnWriteArrayList
  • Verwenden Sie das parallele Fork / Join-Framework
  • Verwenden Sie parallele Streams zur Reduzierung, Zerlegung, Zusammenführung, Pipeline, Leistung usw.

Lassen Sie uns zunächst die grundlegende Verwendung der Parallelverarbeitung mithilfe von Threads mithilfe der Klasse "Thread" und der Schnittstelle "Runnable" sowie die grundlegende Verwendung der exklusiven Verarbeitung und der synchronen Verarbeitung lernen. Geben Sie für die exklusive Verarbeitung den Modifikator "synchronized" für die Methode oder den Block an und verwenden Sie für die synchrone Verarbeitung "java.util.concurrent.CyclicBarrier". Beachten Sie, dass die "Runnable" -Schnittstelle eine funktionale Schnittstelle mit einer abstrakten Methode, "run ()", ist, sodass eine Lambda-Ausdruckszuweisung möglich ist. Ich denke, es gab ungefähr zwei Fragen im Executator-Framework, aber ich glaube nicht, dass Sie die Bewegung verstehen können, ohne es zu wissen. Das Execurator-Framework führt das Konzept eines Thread-Pools ein, der während der Instanziierung mehrere Threads gleichzeitig erzeugt und diese speichert, bis sie verwendet werden. Darüber hinaus implementiert es die Ausführungsplanungsfunktion jedes Threads und zeigt eine hervorragende Leistung bei hervorragender Wiederverwendbarkeit des Threads. Als Testvorbereitung müssen Sie das Verhalten von "Executor Service" verstehen. Im folgenden Code finden Sie ein Beispiel für die Verwendung von "ExecutorService".

Runnable r = new Runnable() {
	@Override
	public void run() {
		for (int i = 0; i < 5; i++) {
			System.out.println("Runnable : " + i);
		}
	}
};

Callable<Integer> c = new Callable<Integer>() {
	@Override
	public Integer call() {
		int i = 0;
		for (; i < 5; i++) {
			System.out.println("Callable : " + i);
		}
		return i;
	}
};

ExecutorService es = null;
try {
	es = Executors.newFixedThreadPool(3);

	es.execute(r);
	Future<?> f1 = es.submit(r);
	Future<Integer> f2 = es.submit(c);
	
	System.out.println(f1.get() + " : " + f2.get());
} catch (InterruptedException | ExecutionException e) {
	e.printStackTrace();
} finally {
	es.shutdown();
}

Executors.newFixedThreadPool (3) erstellt eine ExecutorService-Instanz es, die einen Thread-Pool mit einer festen Anzahl von 3 Threads darstellt. Führen Sie die vordefinierten "Runnable" -Tasks auf dieser Instanz mit "execute ()" in einem von drei Threads aus. Aufgaben können auch die "Callable " - Schnittstelle anstelle der "Runnable" -Schnittstelle verwenden. Die Unterschiede sind in der folgenden Tabelle aufgeführt.

Name der funktionalen Schnittstelle Abstrakte Methode Rückgabetyp aktivierte Ausnahmewurffähigkeit
java.lang.Runnable run() Sie müssenvoidZu unmöglich
java.util.concurrent.Callable call() Geben Sie Parameter einTSpezifiziert durch throwsMöglich durch Spezifikation

Zu diesem Zeitpunkt weist die Thread-Ausführungsfunktion eines der folgenden vier Muster auf.

Methodenname Rückgabetyp Nach dem Ausführen der AufgabeFutureWert gespeichert in
execute(Runnable task) void -
submit(Runnable task) Future<?> null
submit(Runnable task, T t) Future<T> t
submit(Callable<T> task) Future<T> Callable<T>vonT call()Wert zurückgegeben von

Future <T> ist eine Schnittstelle, die das Ergebnis der Aufgabenausführung darstellt. Sie sollten sich an den Mechanismus erinnern, den der Thread wartet, bis die Aufgabe durch get () abgeschlossen ist. Wenn sie abgeschlossen ist, wird das Ergebnis vom Typ T unverändert zurückgegeben. ist. Von oben in der Zeile "System.out.println (f1.get () +": "+ f2.get ());"

null : 5

Wird ausgegeben. Führen Sie abschließend "shutdown ()" aus, um "es" herunterzufahren und keine neuen Aufgaben mehr anzunehmen. Wenn Sie die Methode shutdown () nicht aufrufen, wird das Programm nicht beendet und wartet weiter, nachdem alle Threads die Verarbeitung abgeschlossen haben. Ich denke, dass das Bild nur durch Erinnern an die oben beschriebene Reihe von Operationen herauskommt. Zusätzlich zu "CyclicBarrier" implementiert das Paket "java.util.concurrent" thread-sichere Schnittstellen "List", "Map", "Set" und "Queue". Siehe zum Beispiel den folgenden Code.

List<Integer> list = new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4));

new Thread(){
	@Override
	public void run() {
		for (Integer num : list) {
			System.out.println("Thread : " + num);
		}
	}
}.start();

for (Integer num : list) {
	System.out.println("Remove : " + num);
	list.remove(num);
}

Auf den ersten Blick scheint sich das Ergebnis mit jeder Ausführung zu ändern, aber in Wirklichkeit wird immer die Ausnahme "java.util.ConcurrentModificationException" ausgelöst.

Exception in thread "Thread-0" Exception in thread "main" java.util.ConcurrentModificationException
	at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
	at java.util.ArrayList$Itr.next(ArrayList.java:851)
	at Main.main(Main.java:18)
java.util.ConcurrentModificationException
	at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
	at java.util.ArrayList$Itr.next(ArrayList.java:851)
	at Main$1.run(Main.java:12)

Die Anweisung "for" der Java-Erweiterung ruft den in der Auflistung implementierten Iterator (= "Iterator" -Schnittstelle) auf, fügt jedoch während der iterativen Verarbeitung durch diesen Iterator Elemente der nicht threadsicheren Auflistung wie "ArrayList" hinzu. / Dies liegt daran, dass die Spezifikation beim Löschen eine Ausnahme "java.util.ConcurrentModificationException" auslöst. Ich persönlich denke, dass dies eines der Probleme ist, die Sie erst verstehen können, wenn Sie es tatsächlich implementieren. Als Workaround

List<Integer> list = new ArrayList<>(Arrays.asList(0, 1, 2, 3, 4));

Sie können die Zeile wie unten gezeigt durch die thread-sichere Klasse "java.util.concurrent.CopyOnWriteArrayList" ersetzen.

List<Integer> list = new CopyOnWriteArrayList<>(Arrays.asList(0, 1, 2, 3, 4));

Neben "CopyOnWriteArrayList" gibt es viele thread-sichere Sammlungen, aber vorerst Zusammenfassung der im Paket "java.util.concurrent" enthaltenen Klassen Sie müssen nur einen kurzen Blick auf (/jp/8/docs/api/java/util/concurrent/package-summary.html) werfen, um festzustellen, welche Sammlungen threadsicher sind. Ich erinnere mich, dass jeweils eine Frage aus dem Atomic- und dem Fork / Join-Framework gestellt wurde. Für atomare (= eine Reihe unteilbarer Operationen) wurde die Klasse "AtomicInteger" festgelegt, die eine Methode definiert, die eine exklusive Verarbeitung wie den Modifikator "synchronisiert" für primitive Typen wie "int" ausführt. Das Fork / Join-Framework benötigt nur ein grobes Verständnis für das Schreiben des Gesamtcodes.

JDBC-Datenbankanwendung

  • Beschreibt die Kernschnittstellen der JDBC-API, einschließlich der Schnittstellen "Driver", "Connection", "Statement" und "ResultSet" sowie deren Beziehung zur Implementierung des Anbieters.
  • Identifizieren Sie die Komponenten, die für die Verbindung mit der Datenbank erforderlich sind, mithilfe der DriverManager-Klasse, z. B. der JDBC-URL
  • Stellen Sie Abfragen und lesen Sie Ergebnisse aus der Datenbank, einschließlich Erstellen von Anweisungen, Abrufen von Ergebnismengen, Wiederholen von Ergebnissen und ordnungsgemäßes Schließen von Ergebnismengen / Anweisungen / Verbindungen

JDBC erfordert ein gewisses Maß an Verständnis aus den folgenden beiden Perspektiven.

In der eigentlichen Prüfung erinnere ich mich, dass nur etwa 4 Fragen zur Verwendung der letzteren JDBC-API gestellt wurden, aber das Wissen über die erstere kann auch als Multi-Choice-Frage gestellt werden, sodass es notwendig ist, die Funktionsweise des Systems zu verstehen. Überlegen. Von nun an wird in diesem Artikel nur noch Letzteres erläutert. Es ist äußerst wichtig zu verstehen, wie die JDBC-API aus dem grundlegenden Codierungsfluss verwendet wird, mit dem die Datenbank in der folgenden Reihenfolge verbunden / betrieben werden kann.

  1. Ein Objekt, das die von DriverManager.getConnection () generierte "Connection" -Schnittstelle implementiert
  2. Ein Objekt, das die von Connection.createStatement () generierte Statement-Schnittstelle in 1 implementiert.
  3. Ein Objekt, das die vonStatement.executeQuery () in 2 generierte ResultSet-Schnittstelle implementiert.

Alle drei Objekte können mit angewendeten Ressourcen ausprobiert und "close ()" ausgeführt werden. Beachten Sie also, dass das Ausführen einer Methode für jedes geschlossene Objekt eine "SQLException" auslöst. Beispiel: Für ein bestimmtes "privates statisches Finale" ist die Variable "URL" eine URL, die eine Verbindung zu einem JDBC vom Typ "String" herstellen kann

try (Connection cn = DriverManager.getConnection(URL);
	 Statement st = cn.createStatement()) {
	ResultSet rs1 = st.executeQuery("SELECT id FROM shop");
	ResultSet rs2 = st.executeQuery("SELECT name FROM shop");

	if (rs1.next()) {
		System.out.println(rs1.getInt(1));
	}
	if (rs2.next()) {
		System.out.println(rs2.getString(1));
	}
} catch (SQLException e) {
	e.pribntStackTrace();
}

Wenn Sie die Variable "st" vom Typ "Anweisung" wie in "wiederverwenden", wird "rs1" an dem Punkt geschlossen, an dem "rs2" generiert wird. Also löst rs1.next () eine SQLException aus. Beachten Sie, dass ResultSet sich um den Zeilen- / Spaltenindex kümmert, der bei 1 beginnt, nicht bei 0. Daher wird für eine Variable vom Typ "ResultSet" "rs.getString (0)" usw. kompiliert, aber "SQLException" wird zur Laufzeit ausgelöst. Rs.absolute (0) löst jedoch zur Laufzeit keine SQLException für Kompilierungsfehler aus. Dies liegt daran, dass die Ausführung von "rs.absolute (0)" in die Leerzeile vor der ersten Zeile von "rs" verschoben wird. Übrigens gibt diese Methode den Typ "boolean" und das Ergebnis der erfolgreichen Verschiebung zurück. Gibt true zurück als). Darüber hinaus wurden die folgenden Fragen gestellt, und beide wurden einzeln gestellt.

Lokalisierung

  • Erläutern Sie die Vorteile der Lokalisierung Ihrer Anwendung
  • Verwenden Sie das Objekt "Gebietsschema", um das Gebietsschema zu lesen und festzulegen
  • Eigenschaften Dateien erstellen und lesen
  • Erstellen Sie ein Ressourcenpaket für jedes Gebietsschema und laden Sie das Ressourcenpaket in Ihre Anwendung

Es gibt zwei Möglichkeiten, eine "Gebietsschema" -Instanz zu initialisieren, die eine bestimmte Region darstellt:

Trotz der Tatsache, dass viele der aktuellen Java-Standard-APIs nicht "new" verwenden, weist die in Java 8 neu hinzugefügte "Locale" -Klasse ein ungewöhnliches Design auf, das mit einem Konstruktor initialisiert werden kann. Die obige Initialisierungsmethode für das Gebietsschema wurde tatsächlich gefragt. Es kann auch von der "Locale.Builder" -Klasse initialisiert werden, die eine "statische" verschachtelte Klasse der "Locale" -Klasse ist, aber ich denke, dass es in den später beschriebenen Scheinfragen und tatsächlichen Tests keine Initialisierung gab. .. Obwohl in Java8 nicht neu hinzugefügt, lautet die abstrakte Klasse "ResourceBundle", die ein Ressourcenpaket darstellt, das Informationen wie Sprache, numerischen Wert und Durchgangsinformationen für jede bestimmte Region zentral verwaltet, [Standard-API](https: //). Es ist unter docs.oracle.com/javase/jp/8/docs/api/java/util/ResourceBundle.html vorhanden. In der Java-Standard-API existieren die folgenden beiden Methoden seit langem als Methode zur Beschreibung der oben genannten Informationen zur Realisierung des Ressourcenpakets.

Im eigentlichen Test erinnere ich mich, dass nur die letztere der beiden oben genannten Entwurfsmethoden gefragt wurde, aber ich wurde auch gefragt, wie das Ressourcenpaket damit verwendet werden soll. In diesem Artikel möchte ich beides als Beispiele nennen. Schreiben Sie zunächst für die erstere eine Klasse, die die folgenden Ressourcen darstellt.

Test_ja_JP.java


package com.gold.eight.java;

import java.util.ListResourceBundle;

public class Test_ja_JP extends ListResourceBundle {
	@Override
	protected Object[][] getContents() {
		String[][] contents = {
			{"capital", "Tokyo"},
			{"currency", "yen"},
			{"language", "Japanese"}
		};
		return contents;
	}
}

Denken Sie daran, dass der Grund, warum der Rückgabewert "Object [] []" ist, aber "String [] []" zurückgibt, darin besteht, dass Java-Arrays kovariant sind, wie in Generics beschrieben. Das 0. Element ist der Schlüsselwert und das 1. Element ist der Schlüsselwert, z. B. "java.util.Map <String, String>" für den "String []", der als Nest im "String [] []" vorhanden ist. Geben Sie den Wert ein, der dem Schlüsselwert entspricht. Hier lautet der Klassenname "Test_ja_JP", aber "Test" wird als Basisname bezeichnet, gefolgt vom Unterstrich, um den Sprachcode und den Ländercode der Gebietsschemainformationen zu beschreiben. Verwenden wir diese Ressource nun wie folgt als Ressourcenpaket.

Main.java


package com.gold.eight.java;

import java.util.Locale;
import java.util.ResourceBundle;

public class Main {
	public static void main(String[] args) {
		ResourceBundle rb = ResourceBundle.getBundle("com.gold.eight.java.Test", Locale.JAPAN);
		System.out.println(rb.getString("capital"));
		System.out.println(rb.getString("currency"));
		System.out.println(rb.getString("language"));
	}
}

Wenn Sie die beiden oben genannten Java-Dateien kompilieren und ausführen, lautet die Ausgabe wie folgt.

Tokyo
yen
Japanese

Laden Sie die Ressource mit der Zeile "ResourceBundle rb = ResourceBundle.getBundle (" com.gold.eight.java.Test ", Locale.JAPAN);". Zu diesem Zeitpunkt müssen Sie "package name.base name" als Zeichenfolge in das erste Argument von "getBundle ()" schreiben. Da die Instanz "Locale" als zweites Argument angegeben werden kann, habe ich "Local.JAPAN" geschrieben, das dem Sprachcode und dem Ländercode entspricht. Beim Lesen der in die Ressource geschriebenen Informationen wird getString () der Resourcebundle-Instanz verwendet, um die Schlüsselwertzeichenfolge als Argument anzugeben. Wenn jedoch ein nicht vorhandener Schlüsselwert angegeben wird, java.util. MissingResourceException wird ausgelöst. Die letztere Methode zum Erstellen einer Eigenschaftendatei kann auch im folgenden Format anstelle von Test_ja_JP.java beschrieben werden.

Test_ja_JP.properties


capital=Tokyo
currency=yen
language=Japanese

Auch hier ist der Dateiname der Basisname, gefolgt von einem Unterstrich, und der Sprachcode und der Ländercode der Gebietsschemainformationen werden beschrieben. Wenn Sie es als Ressourcenpaket verwenden möchten, ist es dasselbe wie "Main.java".

Studienbericht

Ich werde so viel schreiben, wie ich mich erinnern kann, wie ich von meinem Studienbeginn bis zu meinem Goldaufenthalt verbracht habe.

2016/9/10〜

Obwohl ich Silber erworben hatte, fühlte ich mich mit meiner Selbstverbesserung nicht zufrieden und beschloss, am nächsten Tag Gold zu erwerben.

2016/9/17〜

Ich habe das Oracle Certification Textbook Java Programmer Gold SE 8 (allgemein bekannt als lila Buch) erhalten, das ich bei Amazon gefunden habe habe angefangen. Imgur Es ist eher ein Lehrbuch als eine Sammlung von Problemen, also lese ich es drei oder vier Tage die Woche, wenn auch unregelmäßig. Ich glaube, ich habe von Mitte bis Ende Oktober 2016 angefangen, die zweite Runde zu lesen. Unterstreichen Sie die erstmaligen Klassen und Methoden und implementieren Sie sie manchmal selbst, während Sie sich die [offizielle API-Sammlung] ansehen (https://docs.oracle.com/javase/jp/8/docs/api/). Ich vertiefte mein Verständnis.

2016/10/23〜 Beim Lesen der zweiten Runde des lila Buches handelt es sich um eine Gold-Version der Problem-Sammlung, die zum Zeitpunkt der Korrespondenz mit Silber [Gründliche Erfassung der Java SE 8 Gold-Problem-Sammlung [1Z0-809]](https: // www .amazon.co.jp / dp / 4295000035 / ref = cm_sw_r_tw_dp_x_WjptybSP18FB5) (allgemein bekannt als Kuromoto) wurde veröffentlicht und ich fand es sofort bei Amazon. Imgur Silvers schwarzes Buch hat eine höfliche Erklärung, und Fragen, die genau wie die Scheinfragen am Ende des Kapitels aussehen, wurden in der eigentlichen Prüfung gestellt. Also beschloss ich, es zu lösen, nachdem ich das lila Buch zwei Runden gelesen und verstanden hatte. Ich glaube, ich habe von Anfang bis Mitte November die erste Seite geöffnet.

2016/11/23 Ich las mehr als zwei Runden lang lila Bücher und ungefähr die Hälfte der schwarzen Bücher, also entschied ich mich, mich für die Prüfung zu bewerben. Mein Ziel war es, im November Gold zu bekommen, aber ich hatte keine andere Wahl, als mich am 3. Dezember zu bewerben, da es kein Testzentrum in der Nähe gab, in dem ich die Prüfung im November ablegen konnte.

2016/12/3 Testtag. Als ich es tatsächlich erhielt, fühlte ich, dass es einfacher war, als ich es für lila und schwarze Bücher erwartet hatte. Nach ungefähr einer Stunde habe ich alles gelöst, einschließlich der Überprüfung, und die Antwort gesendet. Kurz danach schickte mir CertView die Ergebnisse und ich wusste, dass sie bestanden wurden. Imgur

Impressionen

Schließlich werde ich bis zum Bestehen darüber schreiben und was mir nach dem Bestehen aufgefallen ist. Das erste, was mir aufgefallen ist, ist, dass ich mit der Aktualisierung des offiziellen API-Designs den Ablauf der Designhistorie irgendwie verstanden habe, z. B. keine Laufzeit zur Laufzeit auszulösen, sondern es so weit wie möglich zu einem Kompilierungsfehler zu machen **. Das Konzept der Ressourcenpakete wurde beispielsweise vor dem Erscheinen der Generika (Java 5) veröffentlicht. Der Rückgabetyp von "getContents ()", einer abstrakten Methode von "ListResourceBundle", lautet "Object [] []. Es ist `geworden. Damit

@Override
protected Object[][] getContents() {
	Object[][] contents = {
		{"A", "1"},
		{"B", 2},
		{"C", 3.0}
	};
	return contents;
}

Sie können beängstigenden Code wie diesen kompilieren, als würden Sie mich bitten, eine "java.lang.ClassCastException" auszulösen. Mit der Einführung der danach hinzugefügten Generika können wir den Entwurfsablauf irgendwie verstehen, um das Risiko des Auslösens von "java.lang.ClassCastException" zu verringern, indem wir entscheiden, wo der Typ zur Kompilierungszeit statisch bestimmt werden kann ( Nun, Sie können mit instance of ...) wirken. In jüngerer Zeit hat Java 8 auch den Typ "Optimal " hinzugefügt, mit dem versucht wird, die berüchtigte "java.lang.NullPointerException" so weit wie möglich zu reduzieren. Infolgedessen kann eine frühzeitige Fehlererkennung im Entwicklungsprozess erwartet werden, und das Risiko eines Ausfalls des Betriebssystems wird verringert. Außerdem können ** Konstruktoren wie die Console-Klasse und die LocalDateTime-Klasse ausgeblendet werden, indem "private" **, "Path" -Schnittstelle, "ExecuratorService" -Schnittstelle usw. angegeben werden. ** Abstrakte Klassen und Schnittstellen verwenden "new". In letzter Zeit nimmt die Anzahl der Designs, die nicht so viele Konstruktoren wie möglich verwenden, zu, indem die Tatsache ausgenutzt wird, dass Instanzen nicht verwendet werden können. Dies liegt daran, dass der Designer keine Klassen und Methoden verwenden kann, die durch nicht erweiterte "Erweiterungen" / "Implementierungen" neu definiert wurden. Es wäre sowohl für API-Designer als auch für API-Benutzer ein Problem, wenn eine Ausnahme aufgrund einer falschen Reihenfolge der Methodenausführung immer durch Ausführen einer Methode mit einer falschen Definitionsänderung ausgelöst wird. Trotzdem sind die meisten Anbieterqualifikationen für Neulinge teuer. Ich habe ein Rabatt-Ticket beantragt, als ich die Gold-Prüfung abgelegt habe, aber wenn ich die Prüfungsgebühr ordnungsgemäß bezahlt habe, würde es 26.600 Yen für Silber und 26.600 Yen für Gold kosten, was insgesamt 53.200 Yen entspricht. Nun, es scheint, dass es Qualifikationen für Prüfungsgebühren gibt, die viel höher sind. .. Übrigens scheint Java 9 im März 2017 veröffentlicht zu werden, aber werden die Bronze-, Silber- und Gold-Qualifikationen von Java 9 ebenso wie Java 8 angezeigt? Wenn ja, denke ich, dass Sie Java 9 Gold erhalten können, indem Sie das Upgrade auf Java SE 9 Programmer bestehen. Wenn Sie jedoch die Prüfungsgebühr von 26.600 Yen nacheinander zahlen, müssen Sie auch die Betriebskosten bezahlen. Trotzdem möchte ich mit den neuesten Trends in Java Schritt halten, sofern ich kein Qualifikationsbegeisterter bin. Wenn es jedoch ein Upgrade auf Java SE 9 Programmer gäbe, wäre das Problem mit Project Jigsaw, dem Hauptmerkmal von Java 9, das größte? ~~ jshell, ich glaube nicht, dass ich überhaupt ein Problem machen kann. ~~

Es war ein schlechter Artikel, aber danke, dass Sie bis zum Ende gelesen haben.

Recommended Posts

Lassen Sie uns über die vorübergehende Erfahrung von Java SE 8 Programmer II sprechen
Geschichte des Bestehens von Java Silver SE8 (Oracle Certified Java Programmer, Silver SE 8)
Neue Themen aus der Java SE 11 Programmer II-Prüfung
Java SE Bronze (1Z0-818) Erfahrung bestehen
Die Geschichte von Java Gold SE8
[Qualifikation] Java Silver SE11 Passing Experience
Oracle Certified Java Silver SE 8 Passing-Erfahrung
Informationen zur Beschreibungsreihenfolge der Java-Systemeigenschaften
Über die Idee anonymer Klassen in Java
Probieren Sie Progate Free Edition [Java II]
Java Silver Passing Erfahrung
Oracle Certified Java Programmer, Erfahrung mit Silver SE 8-Zertifizierungsprüfungen
Java Se 8 Programmierer Ⅰ Memo
Erfahrung mit dem Bestehen von Java Silver als neuer Absolvent
[Java Silver] Lernmethode, die Java SE 8 Silver bestanden hat [Erfahrung bestanden]
Erlangte Oracle Certified Java Programmer Silver SE 8 Prüfungserfahrung
Über den Betrieb der Java-Lesesitzung BOF findet seit 1998 monatlich statt
Die Falle, die die Standardimplementierung der Java 8-Schnittstelle mit sich bringt
FizzBuzz (@Java) von Bokuga Kanga Etasaikyo, der seit 1 Jahr Programmierer ist
[Java] Ich habe über die Vorzüge und Verwendungen von "Schnittstelle" nachgedacht.
Über den Umgang mit Null
Über Java-Instanzen
[Erfahrung] Java SE 8 Silver bestanden
Beim Übergeben von Java Gold SE 8
Informationen zur Beschreibung von Docker-compose.yml
Java SE8 Silver Passing Erfahrung
Die Geschichte, das Verhalten von String durch Passieren von Java nicht zu kennen
[Rails] Sprechen Sie darüber, wie Sie auf den Rückgabewert von where achten
Eine Geschichte über das Erreichen der League Of Legends-API mit JAVA
Lassen Sie uns eine TODO-App in Java 5 erstellen. Schalten Sie die Anzeige von TODO um
Das Verhalten von JS auf Java SE 8 Nashorn änderte sich plötzlich
Lassen Sie uns die Java 8-Grammatik aus der Sicht der iOS-Ingenieure zusammenfassen
Über das Verhalten von Ruby Hash # ==
[Java] Löschen Sie die Elemente von List
Über die Grundlagen der Android-Entwicklung
Über Biocontainer fastqc und Java
[Java Edition] Geschichte der Serialisierung
Über Lambda, Stream, LocalDate von Java8
Erhaltener Oracle Certified Java Programmer, Gold SE 8
Informationen zur aktuellen Entwicklungsumgebung (Java 8)
Informationen zur Rolle der Initialisierungsmethode
Denken Sie an die 7 Regeln von Optional
Der Ursprung von Java-Lambda-Ausdrücken
Informationen zur Protokollebene von java.util.logging.Logger
Sprechen Sie über die Vorteile von Datenbankbindungsvariablen (② Verdienst: Verhinderung der SQL-Injection)
Lassen Sie uns das Ergebnis der Analyse von Java-Bytecode in einem Klassendiagramm ausdrücken
Über die Klassifizierung und das Konzept von Immutable / Mutable / Const / Variable von Java und Kotlin.
Was ich getan habe, um den Oracle Certified Java Programmer, Silver SE 8, zu erhalten