Klicken Sie, wenn Ihnen das Projekt gefällt. Ihre Beiträge sind herzlich willkommen.
Multithreading
Sammlungen
Java-Datenbankkonnektivität (JDBC)
Java-Programme
Java-String-Methoden
Jakarta-Serverseiten (JSP)
Servlets
Java-Multiple-Choice-Fragen
Java-Entwurfsmuster
Überwintern
Grundlagen des Spring Frameworks
Einführung
Java-Architektur
Java-Datentypen
Java-Methoden
Funktionale Java-Programmierung
Java-Lambda-Ausdrücke
Java-Klassen
Java-Konstruktoren
Java-Array
Java-Strings
Java-Reflexion
Java-Streams
Reguläre Java-Ausdrücke
Java-Dateiverwaltung
Java-Ausnahmen
Java-Vererbung
Überschreiben von Java-Methoden
Java-Polymorphismus
Java-Abstraktion
Java-Schnittstellen
Java-Kapselung
Java-Generika
Verschiedenes
Standardmäßig Schnittstellenmethoden;
Lambda-Ausdrücke;
Funktionale Schnittstellen;
Verweise auf Methoden und Konstruktoren;
Wiederholbare Anmerkungen
Anmerkungen zu Datentypen;
Reflexion für Methodenparameter;
Stream-API zum Arbeiten mit Sammlungen;
Paralleles Sortieren von Arrays;
Neue API zum Arbeiten mit Datum und Uhrzeit;
Neue JavaScript-Nashorn-Engine;
Mehrere neue Klassen für Thread-sicheren Betrieb hinzugefügt;
Eine neue API für Calendar
und Locale
hinzugefügt;
Unterstützung für Unicode 6.2.0 hinzugefügt;
Eine Standardklasse für die Arbeit mit Base64 hinzugefügt;
Unterstützung für vorzeichenlose Arithmetik hinzugefügt;
Verbesserte Konstruktorleistung java.lang.String(byte[], *)
und Methode java.lang.String.getBytes()
;
Eine neue Implementierung AccessController.doPrivileged
, mit der Sie eine Teilmenge von Berechtigungen festlegen können, ohne alle * anderen Zugriffsebenen überprüfen zu müssen;
Passwortbasierte Algorithmen sind robuster geworden;
Unterstützung für SSL/TLS Server Name Indication (NSI) im JSSE-Server hinzugefügt;
Verbesserter Schlüsselspeicher (KeyStore);
SHA-224-Algorithmus hinzugefügt;
JDBC-Brücke – ODBC entfernt;
PermGen wird entfernt, die Methode zum Speichern von Metadaten von Klassen wird geändert;
Möglichkeit, Profile für die Java SE-Plattform zu erstellen, die nicht die gesamte Plattform, sondern einen Teil davon umfassen;
Werkzeuge
Dienstprogramm jjs
für die Verwendung von JavaScript Nashorn hinzugefügt;
Der Befehl java
kann JavaFX-Anwendungen ausführen;
Dienstprogramm jdeps
zum Analysieren von .class-Dateien hinzugefügt.
↥ zurück nach oben
Nashorn ist eine von Oracle in Java entwickelte JavaScript-Engine. Entwickelt, um die Möglichkeit zu bieten, JavaScript-Code in Java-Anwendungen einzubetten. Im Vergleich zu Rhino, das von der Mozilla Foundation unterstützt wird, bietet Nashorn eine zwei- bis zehnmal bessere Leistung, da es Code kompiliert und Bytecode direkt im Speicher an die Java Virtual Machine überträgt. Nashorn kann JavaScript-Code kompilieren und Java-Klassen generieren, die mit einem speziellen Loader geladen werden. Es ist auch möglich, Java-Code direkt aus JavaScript aufzurufen.
↥ zurück nach oben
jjs
– Dies ist ein Befehlszeilenprogramm, mit dem Sie JavaScript-Programme direkt in der Konsole ausführen können.
↥ zurück nach oben
In Java gibt es drei verschiedene Möglichkeiten, Eingaben des Benutzers in der Befehlszeilenumgebung (Konsole) zu lesen.
1. Verwendung der Buffered Reader-Klasse:
Diese Methode wird verwendet, indem System.in (Standardeingabestream) in einen InputStreamReader eingeschlossen wird, der in einen BufferedReader eingeschlossen wird. Wir können Eingaben vom Benutzer in der Befehlszeile lesen.
/** * Buffered Reader Class */import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;public class Test { public static void main(String[] args) throws IOException { // Enter Daten mit BufferReader BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); // Daten mit readLine lesen String name = reader.readLine(); // Ausgabe der gelesenen Zeile System.out.println(name); } }
2. Verwenden der Scannerklasse:
Der Hauptzweck der Scanner-Klasse besteht darin, primitive Typen und Zeichenfolgen mithilfe regulärer Ausdrücke zu analysieren. Sie kann jedoch auch zum Lesen von Benutzereingaben in der Befehlszeile verwendet werden.
/** * Scanner-Klasse */import java.util.Scanner;class GetInputFromUser { public static void main(String args[]) { // Verwenden des Scanners zum Abrufen von Eingaben vom Benutzerscanner in = new Scanner(System.in); String s = in.nextLine(); System.out.println("Sie haben eine Zeichenfolge eingegeben" + s); int a = in.nextInt(); System.out.println("Sie haben eine Ganzzahl eingegeben " + a); float b = in.nextFloat(); System.out.println("Sie haben float eingegeben " + b); } }
3. Verwenden der Konsolenklasse:
Es hat sich zu einer bevorzugten Methode zum Lesen von Benutzereingaben über die Befehlszeile entwickelt. Darüber hinaus kann es zum Lesen passwortähnlicher Eingaben verwendet werden, ohne dass die vom Benutzer eingegebenen Zeichen wiedergegeben werden. Die Formatzeichenfolgensyntax kann ebenfalls verwendet werden (wie System.out.printf()).
/** * Console Class */public class Sample { public static void main(String[] args) { // Verwenden der Konsole zur Eingabe von Daten vom Benutzer String name = System.console().readLine(); System.out.println(name); } }
↥ zurück nach oben
Der Befehl javap zeigt Informationen zu den Feldern, Konstruktoren und Methoden an, die in einer Klassendatei vorhanden sind. Der Befehl javap (auch Java Disassembler genannt) disassembliert eine oder mehrere Klassendateien.
/** * Java Disassembler */class Simple { public static void main(String args[]) { System.out.println("Hello World"); } }
cmd> javap Simple.class
Ausgabe
Kompiliert aus der Klasse „.java“ Simple { Einfach(); public static void main(java.lang.String[]); }
↥ zurück nach oben
System.out::println
? Der angegebene Ausdruck veranschaulicht die Übergabe eines Verweises auf eine statische Methode einer println()
Klasse System.out
.
↥ zurück nach oben
Streams können sequentiell und parallel sein. Operationen an sequentiellen Streams werden in einem Prozessor-Thread und an parallelen Streams unter Verwendung mehrerer Prozessor-Threads ausgeführt. Parallele Streams verwenden den gemeinsam genutzten Stream ForkJoinPool
über die statische Methode ForkJoinPool.commonPool()
. Wenn es sich in diesem Fall nicht um eine Multicore-Umgebung handelt, wird der Stream sequentiell ausgeführt. Tatsächlich reduziert sich die Verwendung paralleler Streams auf die Tatsache, dass die Daten in den Streams in Teile aufgeteilt werden, jeder Teil auf einem separaten Prozessorkern verarbeitet wird und diese Teile am Ende verbunden werden und abschließende Operationen ausgeführt werden ihnen.
Sie können auch die Schnittstellenmethode parallelStream()
verwenden, um einen parallelen Stream aus der Sammlung Collection
zu erstellen.
Um einen regulären sequentiellen Stream parallel zu machen, müssen Sie die Stream
Methode für das Objekt parallel()
aufrufen. Mit der Methode isParallel()
können Sie herausfinden, ob der Stream parallel ist.
Mithilfe der Methoden parallel()
und sequential()
lässt sich ermitteln, welche Operationen parallel und welche nur sequentiell sein können. Sie können auch aus jedem sequentiellen Stream einen parallelen Stream erstellen und umgekehrt:
Sammlung .stream () .peek ( ... ) // Die Operation ist sequentiell .parallel () .map ( ... ) // Die Operation kann parallel ausgeführt werden, .sequential () .reduce ( ... ) // Operation ist wieder sequentiell
In der Regel werden Elemente in der gleichen Reihenfolge an den Stream übertragen, in der sie in der Datenquelle definiert sind. Beim Arbeiten mit parallelen Streams behält das System die Reihenfolge der Elemente bei. Eine Ausnahme bildet eine Methode forEach()
, die Elemente in zufälliger Reihenfolge ausgeben kann. Und um die Reihenfolge aufrechtzuerhalten, ist es notwendig, die Methode forEachOrdered()
anzuwenden.
Kriterien, die sich auf die Leistung in parallelen Streams auswirken können:
Datengröße – je mehr Daten, desto schwieriger ist es, die Daten zunächst zu trennen und dann zu kombinieren.
Die Anzahl der Prozessorkerne. Theoretisch gilt: Je mehr Kerne ein Computer hat, desto schneller arbeitet das Programm. Wenn die Maschine einen Kern hat, macht es keinen Sinn, parallele Threads zu verwenden.
Je einfacher die Datenstruktur ist, mit der der Stream arbeitet, desto schneller werden Vorgänge ausgeführt. Beispielsweise sind Daten aus ArrayList
einfach zu verwenden, da die Struktur dieser Sammlung eine Folge unabhängiger Daten voraussetzt. Eine Sammlung vom Typ LinkedList
ist jedoch nicht die beste Option, da in einer sequentiellen Liste alle Elemente mit previous / next verbunden sind. Und solche Daten sind schwer zu parallelisieren.
Operationen mit primitiven Typen sind schneller als mit Klassenobjekten.
Es wird dringend empfohlen, keine parallelen Streams für lange Vorgänge (z. B. Netzwerkverbindungen) zu verwenden, da alle parallelen Streams mit einem ForkJoinPool
arbeiten. Solche langen Vorgänge können aufgrund des Mangels an verfügbaren Threads alle parallelen Streams in der JVM stoppen im Pool usw. e. parallele Streams sollten nur für kurze Vorgänge verwendet werden, bei denen die Zählung in Millisekunden erfolgt, nicht jedoch für solche, bei denen die Zählung in Sekunden und Minuten erfolgen kann;
Das Speichern der Reihenfolge in parallelen Streams erhöht die Ausführungskosten, und wenn die Reihenfolge nicht wichtig ist, ist es möglich, das Speichern zu deaktivieren und dadurch die Produktivität zu steigern, indem man eine Zwischenoperation unordered()
verwendet:
Sammlung.parallelStream () .sortiert () .unordered () .collect ( Collectors . toList ());
↥ zurück nach oben
Java Virtual Machine (JVM) ist eine Spezifikation, die eine Laufzeitumgebung bereitstellt, in der Java-Bytecode (.class-Dateien) ausgeführt werden kann. Die JVM ist die Plattform. Die JVM fungiert als „virtuelle“ Maschine oder Prozessor. Die Plattformunabhängigkeit von Java besteht hauptsächlich aus der Java Virtual Machine (JVM). JVM macht dies möglich, weil es die spezifischen Befehlslängen und andere Besonderheiten der Plattform (Betriebssystem) kennt.
Die JVM ist nicht plattformunabhängig. Java Virtual Machine (JVM) stellt die Umgebung zum Ausführen der Java-Datei (. Class-Datei) bereit. Letztendlich kommt es also auf den Kernel an, und der Kernel unterscheidet sich von Betriebssystem (Betriebssystem) zu Betriebssystem. Die JVM wird verwendet, um sowohl den Bytecode in die Maschinensprache für einen bestimmten Computer zu übersetzen als auch die entsprechenden Anweisungen in der Maschinensprache tatsächlich auszuführen.
↥ zurück nach oben
Der Just-In-Time (JIT)-Compiler ist eine Komponente der Laufzeitumgebung, die die Leistung von Java-Anwendungen verbessert, indem sie Bytecodes zur Laufzeit in nativen Maschinencode kompiliert.
Java-Programme bestehen aus Klassen, die plattformneutrale Bytecodes enthalten, die von einer JVM auf vielen verschiedenen Computerarchitekturen interpretiert werden können. Zur Laufzeit lädt die JVM die Klassendateien, bestimmt die Semantik jedes einzelnen Bytecodes und führt die entsprechende Berechnung durch. Die zusätzliche Prozessor- und Speichernutzung während der Interpretation führt dazu, dass eine Java-Anwendung langsamer arbeitet als eine native Anwendung. Der JIT-Compiler hilft, die Leistung von Java-Programmen zu verbessern, indem er Bytecodes zur Laufzeit in nativen Maschinencode kompiliert. Der JIT-Compiler ist standardmäßig aktiviert. Wenn eine Methode kompiliert wurde, ruft die JVM den kompilierten Code dieser Methode direkt auf, anstatt ihn zu interpretieren.
↥ zurück nach oben
Der Java ClassLoader ist ein Teil der Java Runtime Environment, der Java-Klassen dynamisch in die Java Virtual Machine lädt. Java-Code wird vom Javac-Compiler in eine Klassendatei kompiliert und die JVM führt ein Java-Programm aus, indem sie in der Klassendatei geschriebene Bytecodes ausführt. ClassLoader ist für das Laden von Klassendateien aus dem Dateisystem, dem Netzwerk oder einer anderen Quelle verantwortlich.
Arten von ClassLoader:
1. Bootstrap-Klassenlader :
Es lädt Standard-JDK-Klassendateien aus rt.jar und anderen Kernklassen. Es lädt Klassendateien aus jre/lib/rt.jar. Zum Beispiel die Paketklasse java.lang.
2. Klassenlader für Erweiterungen :
Es lädt Klassen direkt aus den JDK-Erweiterungen, normalerweise aus dem Verzeichnis JAVA_HOME/lib/ext
oder einem anderen Verzeichnis wie java.ext.dirs.
3. Systemklassenlader :
Es lädt anwendungsspezifische Klassen aus der Umgebungsvariablen CLASSPATH. Es kann beim Aufrufen des Programms mit den Befehlszeilenoptionen -cp oder classpath festgelegt werden.
↥ zurück nach oben
1. JDK :
Das Java Development Kit ist die Kernkomponente der Java-Umgebung und stellt alle Tools, ausführbaren Dateien und Binärdateien bereit, die zum Kompilieren, Debuggen und Ausführen eines Java-Programms erforderlich sind.
2. JVM :
JVM ist für die Konvertierung des Byte-Codes in den maschinenspezifischen Code verantwortlich. JVM ist außerdem plattformabhängig und bietet zentrale Java-Funktionen wie Speicherverwaltung, Speicherbereinigung, Sicherheit usw. JVM ist anpassbar und wir können Java-Optionen verwenden, um es anzupassen, beispielsweise indem wir der JVM minimalen und maximalen Speicher zuweisen. JVM wird als virtuell bezeichnet, weil es eine Schnittstelle bereitstellt, die nicht vom zugrunde liegenden Betriebssystem und der Maschinenhardware abhängt.
2. JRE :
Java Runtime Environment bietet eine Plattform zum Ausführen von Java-Programmen. JRE besteht aus JVM- und Java-Binärdateien und anderen Klassen, um jedes Programm erfolgreich auszuführen.
↥ zurück nach oben
1. Java-Heap-Speicherplatz:
Der Java-Heap-Speicherplatz wird von der Java-Laufzeit verwendet, um Objekten und JRE-Klassen Speicher zuzuweisen. Wann immer wir ein Objekt erstellen, wird es immer im Heap-Bereich erstellt.
Die Garbage Collection wird auf dem Heap-Speicher ausgeführt, um den von Objekten verwendeten Speicher freizugeben, der keine Referenz hat. Jedes im Heap-Bereich erstellte Objekt hat globalen Zugriff und kann von überall in der Anwendung aus referenziert werden.
2. Java-Stack-Speicher:
Stack in Java ist ein Speicherabschnitt, der Methoden , lokale Variablen und Referenzvariablen enthält. Lokale Variablen werden im Stack erstellt.
Der Stapelspeicher wird immer in der LIFO-Reihenfolge (Last-In-First-Out) referenziert. Immer wenn eine Methode aufgerufen wird, wird im Stapelspeicher ein neuer Block für die Methode erstellt, um lokale Grundwerte und Verweise auf andere Objekte in der Methode zu speichern.
Sobald die Methode endet, wird der Block nicht mehr verwendet und steht für die nächste Methode zur Verfügung. Die Größe des Stapelspeichers ist im Vergleich zum Heap-Speicher sehr gering.
Unterschied:
Parameter | Stapelspeicher | Heap-Speicherplatz |
---|---|---|
Anwendung | Der Stapel wird während der Ausführung eines Threads nacheinander in Teilen verwendet | Die gesamte Anwendung nutzt zur Laufzeit Heap-Speicherplatz |
Größe | Die Größe des Stacks ist je nach Betriebssystem begrenzt und normalerweise kleiner als der Heap | Es gibt keine Größenbeschränkung für Heap |
Lagerung | Speichert nur primitive Variablen und Verweise auf Objekte, die im Heap-Bereich erstellt werden | Alle neu erstellten Objekte werden hier gespeichert |
Befehl | Der Zugriff erfolgt über das Last-in-First-out-Speicherzuordnungssystem (LIFO). | Auf diesen Speicher wird über komplexe Speicherverwaltungstechniken zugegriffen, zu denen die junge Generation, die alte oder unbefristete Generation und die permanente Generation gehören. |
Leben | Der Stapelspeicher ist nur so lange vorhanden, wie die aktuelle Methode ausgeführt wird | Heap-Speicherplatz ist vorhanden, solange die Anwendung ausgeführt wird |
Effizienz | Im Vergleich zum Heap ist die Zuweisung vergleichsweise viel schneller | Langsamere Zuweisung im Vergleich zum Stapel |
Zuteilung/Freigabe | Dieser Speicher wird automatisch zugewiesen bzw. freigegeben, wenn eine Methode aufgerufen bzw. zurückgegeben wird | Heap-Speicherplatz wird zugewiesen, wenn neue Objekte erstellt werden, und von Gargabe Collector freigegeben, wenn auf sie nicht mehr verwiesen wird |
↥ zurück nach oben
JVM ist ein Programm, das Java-Bytecode verwendet und den Bytecode (Zeile für Zeile) in maschinenverständlichen Code umwandelt. JVM führt einige bestimmte Arten von Operationen aus:
Laden von Code
Überprüfung des Codes
Den Code ausführen
Es bietet den Benutzern eine Laufzeitumgebung
Arten von Speicherbereichen, die von der JVM zugewiesen werden:
1. Classloader : Classloader ist ein Subsystem der JVM, das zum Laden von Klassendateien verwendet wird.
2. Klassenbereich (Methode) : Der Klassenbereich (Methode) speichert klassenspezifische Strukturen wie den Laufzeitkonstantenpool, Feld- und Methodendaten sowie den Code für Methoden.
3. Heap : Dies ist der Laufzeitdatenbereich, in dem Objekte zugewiesen werden.
4. Stack : Der Java Stack speichert Frames. Er enthält lokale Variablen und Teilergebnisse und spielt eine Rolle beim Methodenaufruf und bei der Rückgabe. Jeder Thread verfügt über einen privaten JVM-Stack, der gleichzeitig mit dem Thread erstellt wird.
5. Programmzählerregister : PC-Register (Programmzähler). Es enthält die Adresse der aktuell ausgeführten Java Virtual Machine-Anweisung.
6. Native Method Stack : Er enthält alle in der Anwendung verwendeten nativen Methoden.
↥ zurück nach oben
Die automatische Konvertierung primitiver Datentypen in den entsprechenden Wrapper-Typ wird als Boxing bezeichnet, der umgekehrte Vorgang als Unboxing.
Beispiel: Autoboxen
/** * Autoboxing */class BoxingExample { public static void main(String args[]) { int a = 50; Ganzzahl a2 = neue Ganzzahl(a); // Boxing Integer a3 = 5; // Boxen System.out.println(a2 + " " + a3); } }
Beispiel: Auspacken
/** * Unboxing */class UnboxingExample { public static void main(String args[]) { Integer i = new Integer(50); int a = i; System.out.println(a); } }
↥ zurück nach oben
1. Vorübergehend:
Der transiente Modifikator weist das Java-Objektserialisierungssubsystem an, das Feld auszuschließen, wenn eine Instanz der Klasse serialisiert wird. Wenn das Objekt dann deserialisiert wird, wird das Feld auf den Standardwert initialisiert; Das heißt null für einen Referenztyp und null oder falsch für einen primitiven Typ.
Beispiel:
/** * Transient */public transient int limit = 55; // bleibt nicht bestehenpublic int b; // wird bestehen bleiben
2. Flüchtig:
Der flüchtige Modifikator teilt der JVM mit, dass Schreibvorgänge in das Feld immer synchron in den Speicher geleert werden sollen und dass Lesevorgänge des Felds immer aus dem Speicher gelesen werden sollen. Dies bedeutet, dass als flüchtig markierte Felder in einer Multithread-Anwendung sicher aufgerufen und aktualisiert werden können, ohne dass eine native oder standardmäßige bibliotheksbasierte Synchronisierung verwendet werden muss.
Beispiel:
/** * Volatile */public class MyRunnable implementiert Runnable { private volatile boolean active; public void run() { active = true; while (aktiv) { } } public void stop() { active = false; } }
↥ zurück nach oben
Eine Behauptung ermöglicht es, die Richtigkeit aller im Programm getroffenen Annahmen zu testen. Die Behauptung wird mithilfe der Assert-Anweisung in Java erreicht.
Bei der Ausführung der Behauptung wird davon ausgegangen, dass sie wahr ist. Wenn dies fehlschlägt, gibt JVM einen Fehler namens AssertionError
aus. Es wird hauptsächlich zu Testzwecken während der Entwicklung verwendet.
Die Assert-Anweisung wird mit einem booleschen Ausdruck verwendet und kann auf zwei verschiedene Arten geschrieben werden.
// Erster Weg, Ausdruck zu bestätigen;// Zweiter Weg, Ausdruck1 zu bestätigen: Ausdruck2;
Beispiel:
/** * Behauptungen */public class Beispiel { public static void main(String[] args) { int age = 14; Alter <= 18 angeben: „Kann nicht wählen“; System.out.println("Das Alter des Wählers ist " + Alter); } }
↥ zurück nach oben
1. Letzte Variable:
Endvariablen sind nichts anderes als Konstanten. Wir können den Wert einer endgültigen Variablen nicht ändern, sobald sie initialisiert wurde.
Beispiel:
/** * Final Variable */class Demo { final int MAX_VALUE = 99; void myMethod() { MAX_VALUE = 101; } public static void main(String args[]) { Demo obj = new Demo(); obj.myMethod(); } }
Ausgabe
Ausnahme im Thread „main“ java.lang.Error: Ungelöstes Kompilierungsproblem: Das letzte Feld Demo.MAX_VALUE kann bei beginnersbook.com.Demo.myMethod(Details.java:6)bei beginnersbook.com.Demo.main(Details.java:10) nicht zugewiesen werden.
2. Leere Endvariable:
Eine Endvariable, die zum Zeitpunkt der Deklaration nicht initialisiert ist, wird als leere Endvariable bezeichnet. Wir müssen die leere letzte Variable im Konstruktor der Klasse initialisieren, sonst wird ein Kompilierungsfehler ausgegeben (Fehler: variable MAX_VALUE might not have been initialized
).
Beispiel:
/** * Leere Endvariable */class Demo { // Leere Endvariable final int MAX_VALUE; Demo() { // Es muss im Konstruktor initialisiert werden MAX_VALUE = 100; } void myMethod() { System.out.println(MAX_VALUE); } public static void main(String args[]) { Demo obj = new Demo(); obj.myMethod(); } }
Ausgabe
100
3. Endgültige Methode:
Eine letzte Methode kann nicht überschrieben werden. Das bedeutet, dass eine Unterklasse zwar problemlos die endgültige Methode der übergeordneten Klasse aufrufen, diese jedoch nicht überschreiben kann.
Beispiel:
/** * Final Method */class XYZ { final void demo() { System.out.println("XYZ Class Method"); } }class ABC erweitert XYZ { void demo() { System.out.println("ABC Class Method"); } public static void main(String args[]) { ABC obj = new ABC(); obj.demo(); } }
↥ zurück nach oben
Wenn ein primitiver Typ oder eine Zeichenfolge als Konstante definiert ist und der Wert zur Kompilierungszeit bekannt ist, ersetzt der Compiler den Konstantennamen überall im Code durch seinen Wert. Dies wird als Kompilierzeitkonstante bezeichnet.
Die Kompilierzeitkonstante muss sein:
Für endgültig erklärt
Primitiv oder String
Innerhalb der Deklaration initialisiert
Mit konstantem Ausdruck initialisiert
Sie werden zur Kompilierungszeit durch tatsächliche Werte ersetzt, da der Compiler ihren Wert im Voraus kennt und auch weiß, dass er während der Laufzeit nicht geändert werden kann.
privates final int x = 10;
↥ zurück nach oben
Zugriffsspezifizierer/-modifikatoren helfen dabei, den Umfang einer Klasse, eines Konstruktors, einer Variablen, einer Methode oder eines Datenelements einzuschränken.
In Java stehen vier Arten von Zugriffsmodifikatoren zur Verfügung:
default
– Kein Schlüsselwort erforderlich. Wenn eine Klasse, ein Konstruktor, eine Variable, eine Methode oder ein Datenelement ohne Zugriffsspezifizierer deklariert wird, hat sie den Standardzugriffsbereich, dh sie ist nur innerhalb desselben Pakets zugänglich.
private
– wenn als private deklariert, ist der Zugriffsbereich innerhalb der umschließenden Klasse begrenzt.
protected
– wenn als geschützt deklariert, ist der Zugriffsbereich auf das Einschließen von Klassen, Unterklassen desselben Pakets sowie anderer Pakete beschränkt.
public
– wenn als öffentlich deklariert, überall im Programm zugänglich.
... /* Datenelementvariablen */ String firstName="Pradeep"; /* Standardbereich */ protected isValid=true; /* protected Scope */ private String otp="AB0392"; /* privater Bereich */ public int id = 12334; /* öffentlicher Bereich */ ... ... /* Datenelementfunktionen */ String getFirstName(){ return this.firstName; } /* Standardbereich */ protected boolean getStatus(){this.isValid;} /* protected Scope */ private void genericOtp(){ /* privater Bereich */ this.otp = this.hashCode() << 16; }; public int getId(){ return this.id; } /* öffentlicher Bereich */ ... .../* innere Klassen */ Klasse A{} /* Standardbereich */ geschützte Klasse B{} /* geschützter Bereich */ private Klasse C{} /* privater Bereich */ öffentliche Klasse D{} /* öffentlicher Bereich */ ...
↥ zurück nach oben
In Java sind alle nicht statischen Methoden standardmäßig virtuelle Funktionen . Nur Methoden, die mit dem Schlüsselwort final
gekennzeichnet sind und nicht überschrieben werden können, sowie private methods
, die nicht vererbt werden, sind nicht virtuell.
Beispiel: Virtuelle Funktion mit Schnittstelle
/** * Die Funktion applyBrakes() ist virtuell, da * Funktionen in Schnittstellen so konzipiert sind, dass sie überschrieben werden können. **/interface Bicycle { void applyBrakes(); }class ACMEBicycle implementiert Bicycle { public void applyBrakes() { // Hier implementieren wir applyBrakes() System.out.println("Bremsen angewendet"); // Funktion } }
↥ zurück nach oben
Eine native Methode ist eine Java-Methode (entweder eine Instanzmethode oder eine Klassenmethode), deren Implementierung auch in einer anderen Programmiersprache wie C/C++ geschrieben ist. Darüber hinaus darf eine als nativ markierte Methode keinen Körper haben und sollte mit einem Semikolon enden:
Main.java:
öffentliche Klasse Main { public native int intMethod(int i); public static void main(String[] args) { System.loadLibrary("Main"); System.out.println(new Main().intMethod(2)); } }
Main.c:
#include <jni.h>#include "Main.h"JNIEXPORT jint JNICALL Java_Main_intMethod( JNIEnv *env, jobject obj, jint i) { return i * i; }
Kompilieren und ausführen:
javac Main.javajavah -jni Maingcc -shared -fpic -o libMain.so -I${JAVA_HOME}/include -I${JAVA_HOME}/include/linux Main.cjava -Djava.library.path=. Hauptsächlich
Ausgabe
4
↥ zurück nach oben
Wenn eine Methode als statisch deklariert ist, ist sie Mitglied einer Klasse und gehört nicht zum Objekt der Klasse. Es kann aufgerufen werden, ohne ein Objekt der Klasse zu erstellen. Eine statische Methode kann auch auf statische Datenelemente der Klasse zugreifen.
Für eine statische Methode gelten einige Einschränkungen
Die statische Methode kann kein nicht statisches Datenelement verwenden oder eine nicht statische Methode nicht direkt aufrufen.
this
und super
können nicht im statischen Kontext verwendet werden.
Die statische Methode kann nur auf statische Typdaten zugreifen (statische Typinstanzvariable).
Es ist nicht erforderlich, ein Objekt der Klasse zu erstellen, um die statische Methode aufzurufen.
Eine statische Methode kann in einer Unterklasse nicht überschrieben werden
Beispiel:
/** * Statische Methoden */class Parent { static void display() { System.out.println("Super class"); } }public class Beispiel extensions Parent { void display() // versucht, display() zu überschreiben { System.out.println("Sub class"); } public static void main(String[] args) { Übergeordnetes obj = neues Beispiel(); obj.display(); } }
Dies erzeugt einen Fehler bei der Kompilierung. Die Ausgabe ist wie folgt: −
Beispiel.java:10: Fehler: display() in Beispiel kann display() in Parentvoid nicht überschreiben display() // versucht, display() zu überschreiben ^überschriebene Methode ist statischer1-Fehler
↥ zurück nach oben
Welche Struktur und Merkmale hat die Verwendung eines Lambda-Ausdrucks? Ein Lambda ist eine Reihe von Anweisungen, die in eine separate Variable aufgeteilt und dann wiederholt an verschiedenen Stellen des Programms aufgerufen werden können.
Die Basis des Lambda-Ausdrucks ist der Lambda-Operator , der den Pfeil ->
darstellt. Dieser Operator unterteilt den Lambda-Ausdruck in zwei Teile: Die linke Seite enthält eine Liste von Ausdrucksparametern und die rechte Seite stellt tatsächlich den Hauptteil des Lambda-Ausdrucks dar, in dem alle Aktionen ausgeführt werden.
Der Lambda-Ausdruck wird nicht selbst ausgeführt, sondern bildet die Implementierung der in der Funktionsschnittstelle definierten Methode. Wichtig ist, dass die funktionale Schnittstelle nur eine einzige Methode ohne Implementierung enthalten sollte.
Schnittstelle Operationable { int berechne ( int x , int y ); }public static void main ( String [] args) { Operationable operation = (x, y) - > x + y; int result = operation.calculate (10, 20); System.out.println (Ergebnis); // 30 }
Tatsächlich sind Lambda-Ausdrücke in gewisser Weise eine Kurzform interner anonymer Klassen, die zuvor in Java verwendet wurden.
Lambda-Ausdrücke mit verzögerter Ausführung – werden einmal an einer Stelle des Programms definiert und bei Bedarf beliebig oft und an jeder Stelle des Programms aufgerufen.
Die Parameter des Lambda-Ausdrucks müssen vom Typ her den Parametern der funktionalen Schnittstellenmethode entsprechen:
operation = ( int x, int y) - > x + y;// Beim Schreiben des Lambda-Ausdrucks selbst darf der Parametertyp nicht angegeben werden: (x, y) - > x + y;// Wenn die Methode akzeptiert keine Parameter, dann werden leere Klammern geschrieben, zum Beispiel: () - > 30 + 20 ;// Wenn die Methode nur einen Parameter akzeptiert, dann können die Klammern weggelassen werden: n - > n * n;
Nachfolgende Lambda-Ausdrücke müssen keinen Wert zurückgeben.
Schnittstelle Printable { void print( String s ); } public static void main ( String [] args) { Druckbarer Drucker = s - > System.out.println(s); Printer.print("Hallo Welt"); }// _ Block-Lambda-Ausdrücke_ werden von geschweiften Klammern umgeben. Die modularen Lambda-Ausdrücke können in verschachtelten Blöcken, Schleifen, beim Entwerfen der if-Switch-Anweisung, beim Erstellen von Variablen usw. verwendet werden. D . Wenn Sie einen Lambda-Ausdruck blockieren, muss er einen Wert zurückgeben, er wendet explizit „Anweisungsrückgabeanweisung“ an: Operationable operation = ( int x, int y) - > { if (y == 0 ) { return 0 ; } else { return x / y; } };
Übergabe eines Lambda-Ausdrucks als Methodenparameter
Schnittstellenbedingung { boolean isAppropriate ( int n ); }private static int sum ( int [] Zahlen, Bedingung Bedingung) { int result = 0 ; for ( int i : Zahlen) { if (condition.isAppropriate(i)) { result + = i; } } Ergebnis zurückgeben; }public static void main ( String [] args) { System.out.println(sum ( new int [] { 0 , 1 , 0 , 3 , 0 , 5 , 0 , 7 , 0 , 9 }, (n) - > n ! = 0 )); }
↥ zurück nach oben
Der Zugriff auf externe Bereichsvariablen über einen Lambda-Ausdruck ist dem Zugriff über anonyme Objekte sehr ähnlich.
unveränderliche (effektiv endgültige – nicht unbedingt als endgültig markierte) lokale Variablen;
Klassenfelder
statische Variablen.
Auf die Standardmethoden der implementierten Funktionsschnittstelle darf innerhalb des Lambda-Ausdrucks nicht zugegriffen werden.
↥ zurück nach oben
Wenn die in der Klasse vorhandene Methode bereits alles Notwendige tut, können Sie diese Methode mithilfe des Methodenreferenzmechanismus (Methodenreferenz) direkt übergeben. Das Ergebnis ist genau das gleiche wie bei der Definition eines Lambda-Ausdrucks, der diese Methode aufruft.
Beispiel:
private Schnittstelle Measurable { public int length(String string); }public static void main ( String [] args) { Measurable a = String::length; System.out.println(a.length("abc")); }
Methodenreferenzen sind möglicherweise effizienter als die Verwendung von Lambda-Ausdrücken. Darüber hinaus liefern sie dem Compiler bessere Informationen über den Typ. Wenn Sie zwischen der Verwendung einer Referenz auf eine vorhandene Methode und der Verwendung eines Lambda-Ausdrucks wählen können, sollten Sie immer eine Methodenreferenz verwenden.
↥ zurück nach oben
zur statischen Methode;
pro Instanz-Methode;
an den Konstrukteur.
↥ zurück nach oben
Eine verschachtelte innere Klasse kann auf jede private Instanzvariable der äußeren Klasse zugreifen. Wie jede andere Instanzvariable können wir den Zugriffsmodifikator privat, geschützt, öffentlich und den Standardmodifikator haben.
Beispiel:
/** * Innere Klasse */class Äußere { Klasse Inner { public void show() { System.out.println("In einer verschachtelten Klassenmethode"); } } } Klasse Main { public static void main(String[] args) { Outer.Inner in = new Outer().new Inner(); in.show(); } }
Eine Unterklasse ist eine Klasse, die eine oder mehrere Methoden von einer Oberklasse erbt.
Beispiel:
/** * Sub Class */class Car { //...} Klasse HybridCar erweitert Car { //...}
↥ zurück nach oben
1. Statisches Laden der Klasse:
Das Erstellen von Objekten und Instanzen mit dem Schlüsselwort new
wird als statisches Laden von Klassen bezeichnet. Der Abruf der Klassendefinition und die Instanziierung des Objekts erfolgt zur Kompilierungszeit.
Beispiel:
/** * Statisches Laden der Klasse */class TestClass { public static void main(String args[]) { TestClass tc = new TestClass(); } }
2. Dynamisches Klassenladen:
Zum Laden von Klassen wird die Methode Class.forName()
verwendet. Das dynamische Laden von Klassen erfolgt, wenn der Name der Klasse zur Kompilierungszeit nicht bekannt ist.
Beispiel:
/** * Dynamisches Klassenladen */Class.forName (String className);
↥ zurück nach oben
1. Laufzeitklasse:
Die Klasse java.lang.Runtime ist eine Unterklasse der Object-Klasse und bietet Zugriff auf das Java-Laufzeitsystem. Die Laufzeitinformationen wie Speicherverfügbarkeit, Aufruf des Garbage Collectors usw.
Beispiel:
/** * Laufzeitklasse */public class RuntimeTest { static class Message erweitert Thread { public void run() { System.out.println(" Exit"); } } public static void main(String[] args) { try { Runtime.getRuntime().addShutdownHook(new Message()); System.out.println(" Programm gestartet..."); System.out.println(" 5 Sekunden warten..."); Thread.sleep(5000); System.out.println(" Programm beendet..."); } Catch (Ausnahme e) { e.printStackTrace(); } } }
2. Systemklasse:
Der Zweck der Systemklasse besteht darin, Zugriff auf Systemressourcen bereitzustellen. Es enthält die Barrierefreiheit zu Standardeingang, StandART -Ausgabe, Fehlerausgangsströmen, aktuelle Zeit in Millis, Beendet die Anwendung usw.
↥ Zurück nach oben
1. Verwenden Sie neues Schlüsselwort:
MyObject Object = new myObject ();
2. Verwendung von class.forname ():
MyObject Object = (myObject) class.forname ("subin.rnd.myObject"). NewInstance ();
3.. Mit Clone ():
MyObject ein AnotherObject = new myObject (); myObject Object = (myObject) AnotherObject.clone ();
4.. Verwenden von Objektdeserialisierung:
ObjectInputStream Instream = new ObjectInputStream (AninputStream); myObject Object = (myObject) Instream.ReadObject ();
↥ Zurück nach oben
Unwähme Objekte sind Objekte, die sich nicht ändern. Ein unveränderliches Java -Objekt muss alle seine Felder für interne, private Endfelder haben. Es darf keine Setter implementieren. Es braucht einen Konstruktor, der für jedes einzelne Feld einen Wert nimmt.
Erstellen eines unveränderlichen Objekts:
Fügen Sie keine Settermethode hinzu
Erklären Sie alle Fields endgültig und privat
Wenn ein Feld ein veränderliches Objekt ist, erstellen Sie defensive Kopien davon für Getter -Methoden
Wenn ein an den Konstruktor übergebener veränderlicher Objekt einem Feld zugeordnet werden muss, erstellen Sie eine defensive Kopie davon
Lassen Sie die Unterklassen nicht zulassen, Methoden zu überschreiben.
/** * unveränderliches Objekt */öffentliche Klasse datEntainer {privates Enddatum; public dateContainer () {this.date = new Date (); } public date getDate () {Neues Datum zurückgeben (Datum.getTime ()); } }
↥ Zurück nach oben
Unveränderliche Klasse bedeutet, dass wir seinen Inhalt nicht ändern können, sobald ein Objekt erstellt wurde. In Java sind alle Wrapper -Klassen (wie Integer, Boolean, Byte, Short) und String Class unveränderlich.
Regeln, um unveränderliche Klassen zu erstellen:
Die Klasse muss als endgültig deklariert werden
Datenmitglieder in der Klasse müssen als endgültig deklariert werden
Ein parametrisierter Konstruktor
Getter -Methode für alle Variablen darin
Keine Setter
/** * unveränderliche Klasse */Public Final Class Employee {Finale String PancardNumber; öffentlicher Mitarbeiter (String PancardNumber) {this.PancardNumber = PancardNumber; } public String getPancardNumber () {return pancardNumber; } }
↥ Zurück nach oben
Bootstrap Classloader ist für das Laden von Standard -JDK -Klassendateien von RT.Jar sorgfältig und ist übergeordnet mit allen Klassenladern in Java. In Java gibt es drei Arten von integriertem Klassenloader:
1. Bootstrap -Klasse Loader: Es lädt JDK -interne Klassen, lädt typischerweise RT.Jar und andere Kernklassen Java.lang.* Paketklassen
2. Extensions Class Loader: Es lädt Klassen aus dem JDK -Erweiterungsverzeichnis, normalerweise $ java_home/lib/ext -Verzeichnis.
3. Systemklassenlader: Es lädt Klassen aus dem aktuellen Klassenpfad, der beim Aufrufen eines Programms mit den Befehlszeilenoptionen -cp oder -ClassPaths festgelegt werden kann.
/** * Classloader */import Java.util.logging.level; import Java.util.logging.logger; öffentliche Klasse classLoloadtest {public static void main (String args []) {try {// Druckklassenloader dieses Klassensystems .out.println ("classloader:" + classloadtest.class.getClassloader ()); // Versuch, diese Klasse explizit mithilfe der Erweiterungsklassen -Loader -Klasse zu laden ("explizit Klasse laden", true, classloadtest.class.getClassloader (). getParent ()); } catch (classNotFoundException ex) {logger.getLogger (classLoloadtest.class.getName ()). log (Level.Severe, null, ex); } } }
↥ Zurück nach oben
Verschiedene Möglichkeiten, ein Objekt in Java zu erstellen
Verwenden neuer Schlüsselwort:
class ObjectCreation Example {String -Besitzer; } public class mellClass {public static void main (String [] args) {// Hier erstellen wir ein Objekt von JBT mit neuer KeywordObjectObjectObjectOrcreationExample obj = new ObjectCreationExample (); } }
Verwenden neuer Instanzen (Reflexion)
Klasse createObjectClass {static int j = 10; createObjectClass () {i = j ++; } int i; @Overridepublic String toString () {return "Wert von i:" + i; } } class Mainclass {public static void main (String [] args) {try {class cls = class.forname ("createObjectClass"); createObjectClass obj = (createObjectClass) cls.newinstance (); createObjectClass obj1 = (CreateObjectClass) cls.newinstance (); (); System.out.println (obj); System.out.println (obj1); } catch (classNotFoundException e) {e.printstacktrace (); } catch (InstantiationException e) {e.printstacktrace (); } catch (illegalAccessException e) {e.printstacktrace (); } } }
Verwenden von Klon:
Klasse createObjectWithClone implementiert klonable {@OverrideProtected -Objekt Clone () löscht ClonenotsUsportedexception {return Super.clone (); } int i; static int j = 10; createObjectWithClone () {i = j ++; } @Overridepublic String toString () {return "Wert von i:" + i; } } class Mainclass {public static void main (string [] args) {createObjectWithClone obj1 = new CreateObjectWithClone (); System.out.println (obj1); try {createSoBjectWithClone obj2 = (createObjectWithClone) obj1.clone (); system.out. println (obj2); } catch (clonenotsUsPortedexception e) {e.printstacktrace (); } } }
Verwenden von Classloader
Klasse createObjectWithClassloader {static int j = 10; createObjectWithClassLoader () {i = j ++; } int i; @Overridepublic String toString () {return "Wert von i:" + i; } } public class Mainclass {public static void main (String [] args) {createObjectWithClassloader obj = null; try {obj = (createObjectWithClassader) New MainClass (). getClass () .GetClassLoader (). LoadClass ("createObjectWithClassLoader"). newInstance (); // Ein vollständig qualifizierter Klassenname sollte verwendet werden. } catch (InstantiationException e) {e.printstacktrace (); } catch (illegalAccessException e) {e.printstacktrace (); } catch (classNotFoundException e) {e.printstacktrace (); } System.out.println (obj); } }
↥ Zurück nach oben
Die Objektklasse ist standardmäßig die übergeordnete Klasse aller Klassen in Java.
Verfahren | Beschreibung |
---|---|
öffentliche Final Class getClass () | Gibt das Klassenobjekt dieses Objekts zurück. Die Klassenklasse kann weiter verwendet werden, um die Metadaten dieser Klasse zu erhalten. |
public int hashcode () | Gibt die HashCode -Nummer für dieses Objekt zurück. |
öffentlicher Boolescher gleich (Objekt OBJ) | Vergleicht das angegebene Objekt mit diesem Objekt. |
geschützter Objekt Clone () wirft ClonenotsuptedEdException aus | Erstellt und gibt die genaue Kopie (Klon) dieses Objekts zurück. |
öffentlicher String -ToString () | Gibt die String -Darstellung dieses Objekts zurück. |
öffentliche Finale Leere Benachrichtigung () | Weckt ein einzelnes Thread auf und wartet auf diesen Objekt. |
öffentliche Finale void musifyAll () | Weckt alle Threads auf und wartet auf diesen Objekt. |
Öffentliche Finale Leere Wartezeit (langfristig) löst unterbrochene Ausnahme aus | Bewirkt, dass der aktuelle Thread auf die angegebenen Millisekunden wartet, bis ein anderer Thread benachrichtigt wird (aufgerufen benachrichtigt () oder notifyAll () -Methoden). |
Öffentliche letzte Leere Wartezeit (langfristig, int nanos) wirft InterruptedException aus | Bewirkt, dass der aktuelle Thread auf die angegebenen Millisekunden und Nanosekunden wartet, bis ein anderer Thread benachrichtigt wird (aufgerufen benachrichtigt () oder notifyAll () -Methoden). |
Öffentliche Finale Leere Wait () wirft unterbrochen | Bewirkt, dass der aktuelle Thread wartet, bis ein anderer Thread benachrichtigt wird (aufgerufen benachrichtigt () oder notifyAll () -Methoden). |
Protected void Finalize () wirft Throwable ab | wird vom Müllsammler angerufen, bevor das Objekt Müll gesammelt wird. |
↥ Zurück nach oben
Ein optionaler Optional
Wert ist ein Container für ein Objekt, das möglicherweise einen null
enthält oder nicht. Eine solche Verpackung ist ein bequemes Mittel zur Prävention