Java Language
Nichtzugriffsmodifizierer
Suche…
Einführung
Nicht-Zugriffsmodifizierer ändern die Zugänglichkeit von Variablen und Methoden nicht, bieten jedoch spezielle Eigenschaften .
Finale
final
in Java kann sich auf Variablen, Methoden und Klassen beziehen. Es gibt drei einfache Regeln:
- Die letzte Variable kann nicht erneut zugewiesen werden
- Die endgültige Methode kann nicht überschrieben werden
- letzte Klasse kann nicht verlängert werden
Verwendungen
Gute Programmierpraxis
Einige Entwickler halten es für sinnvoll, eine Variable als final zu markieren, wenn Sie können. Wenn Sie eine Variable haben, die nicht geändert werden soll, markieren Sie sie als final.
Eine wichtige Verwendung des final
Schlüsselworts if für Methodenparameter. Wenn Sie betonen möchten, dass eine Methode ihre Eingabeparameter nicht ändert, markieren Sie die Eigenschaften als endgültig.
public int sumup(final List<Integer> ints);
Dies betont, dass die sumup
Methode die sumup
nicht ändern ints
.
Innere Klasse Zugang
Wenn Ihre anonyme innere Klasse auf eine Variable zugreifen möchte, sollte die Variable als final
markiert werden
public IPrintName printName(){
String name;
return new IPrintName(){
@Override
public void printName(){
System.out.println(name);
}
};
}
Diese Klasse lässt sich nicht kompilieren, als name
, nicht endgültig.
Endgültige Variablen sind eine Ausnahme. Hierbei handelt es sich um lokale Variablen, die nur einmal geschrieben werden und daher als final deklariert werden könnten. Auf endgültige Variablen kann auch von anonymen Klassen zugegriffen werden.
final static
Variable
Auch wenn der folgende Code völlig legal ist, wenn die final
Variable foo
nicht static
, wird sie im static
Fall nicht kompiliert:
class TestFinal {
private final static List foo;
public Test() {
foo = new ArrayList();
}
}
Der Grund ist, lassen Sie uns noch einmal wiederholen, die letzte Variable kann nicht erneut zugewiesen werden . Da foo
statisch ist, wird es von allen Instanzen der Klasse TestFinal
. Wenn eine neue Instanz einer Klasse TestFinal
erstellt wird, wird deren Konstruktor aufgerufen, und foo wird neu zugewiesen, was der Compiler nicht zulässt. Eine korrekte Methode zum Initialisieren der Variablen foo
in diesem Fall entweder:
class TestFinal {
private static final List foo = new ArrayList();
//..
}
oder mit einem statischen Initialisierer:
class TestFinal {
private static final List foo;
static {
foo = new ArrayList();
}
//..
}
final
Methoden sind nützlich, wenn die Basisklasse einige wichtige Funktionen implementiert, die von der abgeleiteten Klasse nicht geändert werden sollen. Sie sind auch schneller als nicht endgültige Methoden, da kein Konzept für virtuelle Tabellen vorhanden ist.
Alle Wrapper-Klassen in Java sind final, wie Integer
, Long
usw. Die Ersteller dieser Klassen wollten nicht, dass jeder Integer beispielsweise in seine eigene Klasse erweitern und das grundlegende Verhalten der Integer-Klasse ändern kann. Eine der Voraussetzungen, um eine Klasse unveränderlich zu machen, besteht darin, dass Unterklassen Methoden nicht überschreiben dürfen. Am einfachsten ist es, die Klasse als final
zu deklarieren.
flüchtig
Der volatile
Modifikator wird bei der Multithread-Programmierung verwendet. Wenn Sie ein Feld als volatile
deklarieren, ist dies ein Signal an Threads, dass sie den neuesten Wert lesen müssen, nicht einen lokal zwischengespeicherten Wert. Darüber hinaus sind volatile
Lese- und Schreibvorgänge garantiert atomar (der Zugriff auf einen volatile
long
oder double
Speicher ist nicht atomar), wodurch bestimmte Lese- / Schreibfehler zwischen mehreren Threads vermieden werden.
public class MyRunnable implements Runnable
{
private volatile boolean active;
public void run(){ // run is called in one thread
active = true;
while (active){
// some code here
}
}
public void stop(){ // stop() is called from another thread
active = false;
}
}
statisch
Das static
Schlüsselwort wird für eine Klasse, eine Methode oder ein Feld verwendet, damit sie unabhängig von jeder Instanz der Klasse funktionieren.
- Statische Felder gelten für alle Instanzen einer Klasse. Sie benötigen keine Instanz, um auf sie zuzugreifen.
- Statische Methoden können ohne eine Instanz der Klasse ausgeführt werden, in der sie sich befinden. Sie können jedoch nur auf statische Felder dieser Klasse zugreifen.
- Statische Klassen können innerhalb anderer Klassen deklariert werden. Sie benötigen keine Instanz der Klasse, in der sie sich befinden, um instanziiert zu werden.
public class TestStatic
{
static int staticVariable;
static {
// This block of code is run when the class first loads
staticVariable = 11;
}
int nonStaticVariable = 5;
static void doSomething() {
// We can access static variables from static methods
staticVariable = 10;
}
void add() {
// We can access both static and non-static variables from non-static methods
nonStaticVariable += staticVariable;
}
static class StaticInnerClass {
int number;
public StaticInnerClass(int _number) {
number = _number;
}
void doSomething() {
// We can access number and staticVariable, but not nonStaticVariable
number += staticVariable;
}
int getNumber() {
return number;
}
}
}
// Static fields and methods
TestStatic object1 = new TestStatic();
System.out.println(object1.staticVariable); // 11
System.out.println(TestStatic.staticVariable); // 11
TestStatic.doSomething();
TestStatic object2 = new TestStatic();
System.out.println(object1.staticVariable); // 10
System.out.println(object2.staticVariable); // 10
System.out.println(TestStatic.staticVariable); // 10
object1.add();
System.out.println(object1.nonStaticVariable); // 15
System.out.println(object2.nonStaticVariable); // 10
// Static inner classes
StaticInnerClass object3 = new TestStatic.StaticInnerClass(100);
StaticInnerClass object4 = new TestStatic.StaticInnerClass(200);
System.out.println(object3.getNumber()); // 100
System.out.println(object4.getNumber()); // 200
object3.doSomething();
System.out.println(object3.getNumber()); // 110
System.out.println(object4.getNumber()); // 200
abstrakt
Abstraktion ist ein Prozess, bei dem die Implementierungsdetails ausgeblendet werden und dem Benutzer nur die Funktionalität angezeigt wird. Eine abstrakte Klasse kann niemals instanziiert werden. Wenn eine Klasse als abstrakt deklariert wird, besteht der einzige Zweck darin, die Klasse zu erweitern.
abstract class Car
{
abstract void tagLine();
}
class Honda extends Car
{
void tagLine()
{
System.out.println("Start Something Special");
}
}
class Toyota extends Car
{
void tagLine()
{
System.out.println("Drive Your Dreams");
}
}
synchronisiert
Synchronized Modifier wird verwendet, um den Zugriff einer bestimmten Methode oder eines Blocks durch mehrere Threads zu steuern. Nur ein Thread kann eine Methode oder einen Block betreten, die als synchronisiert deklariert sind. Das synchronisierte Schlüsselwort funktioniert für die intrinsische Sperre eines Objekts. Im Falle einer synchronisierten Methode sperren die aktuellen Objekte und die statische Methode verwendet ein Klassenobjekt. Jeder Thread, der versucht, einen synchronisierten Block auszuführen, muss zuerst die Objektsperre erwerben.
class Shared
{
int i;
synchronized void SharedMethod()
{
Thread t = Thread.currentThread();
for(int i = 0; i <= 1000; i++)
{
System.out.println(t.getName()+" : "+i);
}
}
void SharedMethod2()
{
synchronized (this)
{
System.out.println("Thais access to currect object is synchronize "+this);
}
}
}
public class ThreadsInJava
{
public static void main(String[] args)
{
final Shared s1 = new Shared();
Thread t1 = new Thread("Thread - 1")
{
@Override
public void run()
{
s1.SharedMethod();
}
};
Thread t2 = new Thread("Thread - 2")
{
@Override
public void run()
{
s1.SharedMethod();
}
};
t1.start();
t2.start();
}
}
vorübergehend
Eine als transient deklarierte Variable wird während der Objektserialisierung nicht serialisiert.
public transient int limit = 55; // will not persist
public int b; // will persist
strictfp
Der striktfp-Modifizierer wird für Gleitkommaberechnungen verwendet. Mit diesem Modifikator wird die Fließkommavariable über mehrere Plattformen hinweg konsistenter und es wird sichergestellt, dass alle Fließkommaberechnungen gemäß den IEEE 754-Standards ausgeführt werden, um Berechnungsfehler (Rundungsfehler), Überläufe und Unterläufe in der 32-Bit- und 64-Bit-Architektur zu vermeiden. Dies kann nicht auf abstrakte Methoden, Variablen oder Konstruktoren angewendet werden.
// strictfp keyword can be applied on methods, classes and interfaces.
strictfp class A{}
strictfp interface M{}
class A{
strictfp void m(){}
}