Szukaj…


Wprowadzenie

Modyfikatory niedostępne nie zmieniają dostępności zmiennych i metod, ale zapewniają im specjalne właściwości .

finał

final w Javie może odnosić się do zmiennych, metod i klas. Istnieją trzy proste zasady:

  • końcowej zmiennej nie można przypisać ponownie
  • ostatecznej metody nie można zastąpić
  • klasa końcowa nie może być przedłużona

Zastosowania

Dobra praktyka programowania

Niektórzy programiści uważają, że dobrą praktyką jest oznaczanie zmiennej końcowej, kiedy jest to możliwe. Jeśli masz zmienną, której nie należy zmieniać, oznacz ją jako ostateczną.

Ważne użycie final słowa kluczowego, jeśli chodzi o parametry metody. Jeśli chcesz podkreślić, że metoda nie zmienia parametrów wejściowych, zaznacz właściwości jako końcowe.

public int sumup(final List<Integer> ints);

Podkreśla to, że metoda sumup nie zmieni ints .

Dostęp do klasy wewnętrznej

Jeśli twoja anonimowa klasa wewnętrzna chce uzyskać dostęp do zmiennej, zmienna powinna być oznaczona jako final

  public IPrintName printName(){
    String name;
    return new IPrintName(){
        @Override
        public void printName(){
            System.out.println(name);
        }
    };
}

Ta klasa nie kompiluje się, ponieważ name zmiennej nie jest ostateczna.

Java SE 8

Wyjątkowo skuteczne są zmienne końcowe. Są to zmienne lokalne, które są zapisywane tylko raz i dlatego mogą być ostateczne. Do efektywnych zmiennych końcowych można również uzyskać dostęp z klas anonimowych.

final static zmienna final static

Mimo że poniższy kod jest całkowicie legalny, gdy final zmienna foo nie jest static , w przypadku static nie będzie się kompilować:

class TestFinal {
    private final static List foo;

    public Test() {
        foo = new ArrayList();
    }
}

Powodem jest to, powtórzmy jeszcze raz, ostatecznej zmiennej nie można przypisać ponownie . Ponieważ foo jest statyczny, jest współużytkowany przez wszystkie instancje klasy TestFinal . Kiedy TestFinal jest nowa instancja klasy TestFinal , wywoływany jest jej konstruktor, dlatego foo zostaje ponownie przypisany, który kompilator nie zezwala. Prawidłowym sposobem na zainicjowanie zmiennej foo w tym przypadku jest:

class TestFinal {
    private static final List foo = new ArrayList();
    //..
}

lub za pomocą inicjatora statycznego:

class TestFinal {
    private static final List foo;
    static {
        foo = new ArrayList();
    }
    //..
}

metody final są przydatne, gdy klasa podstawowa implementuje ważną funkcję, której klasa pochodna nie powinna zmieniać. Są również szybsze niż metody nie-końcowe, ponieważ nie ma w nich pojęcia o wirtualnej tabeli.

Wszystkie klasy otoki w Javie są ostateczne, takie jak Integer , Long itp. Twórcy tych klas nie chcieli, aby ktokolwiek mógł np. Rozszerzyć Integer na własną klasę i zmienić podstawowe zachowanie klasy Integer. Jednym z wymagań, aby klasa była niezmienna, jest to, że podklasy nie mogą zastępować metod. Najprostszym sposobem na to jest zadeklarowanie klasy jako final .

lotny

volatile modyfikator jest stosowany w programowaniu wielowątkowym. Jeśli zadeklarujesz pole jako volatile , jest to sygnał dla wątków, że muszą odczytać najnowszą wartość, a nie lokalnie buforowaną. Co więcej, volatile odczyty i zapisy są gwarantowane jako atomowe (dostęp do volatile long lub double nie jest atomowy), dzięki czemu unika się pewnych błędów odczytu / zapisu między wieloma wątkami.

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;
    }
}

statyczny

static słowo kluczowe jest używane w klasie, metodzie lub polu, aby działały niezależnie od dowolnego wystąpienia klasy.

  • Pola statyczne są wspólne dla wszystkich instancji klasy. Nie potrzebują instancji, aby uzyskać do nich dostęp.
  • Metody statyczne można uruchamiać bez wystąpienia klasy, w której się znajdują. Mogą jednak uzyskiwać dostęp tylko do pól statycznych tej klasy.
  • Klasy statyczne mogą być deklarowane wewnątrz innych klas. Nie potrzebują wystąpienia instancji klasy, w której są tworzone.
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

abstrakcyjny

Abstrakcja to proces ukrywania szczegółów implementacji i pokazywania użytkownikowi tylko funkcjonalności. Klasa abstrakcyjna nigdy nie może zostać utworzona. Jeśli klasa zostanie zadeklarowana jako abstrakcyjna, jedynym celem jest rozszerzenie klasy.

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");
    }
}

zsynchronizowany

Zsynchronizowany modyfikator służy do kontrolowania dostępu do określonej metody lub bloku za pomocą wielu wątków. Tylko jeden wątek może wejść do metody lub bloku, który jest zadeklarowany jako zsynchronizowany. Zsynchronizowane słowo kluczowe działa na wewnętrzną blokadę obiektu, w przypadku metody zsynchronizowanej blokada bieżących obiektów, a metoda statyczna używa obiektu klasy. Każdy wątek próbujący wykonać zsynchronizowany blok musi najpierw uzyskać blokadę obiektu.

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();
    }
}

przemijający

Zmienna zadeklarowana jako przejściowa nie będzie serializowana podczas serializacji obiektu.

public transient int limit = 55;   // will not persist
public int b; // will persist

strictfp

Java SE 1.2

modyfikator strictfp służy do obliczeń zmiennoprzecinkowych. Ten modyfikator sprawia, że zmienna zmiennoprzecinkowa jest bardziej spójna na wielu platformach i zapewnia, że wszystkie obliczenia zmiennoprzecinkowe są wykonywane zgodnie ze standardami IEEE 754, aby uniknąć błędów obliczeniowych (błędów zaokrąglania), przelewów i niedopełnień w architekturze 32-bitowej i 64-bitowej. Nie można tego zastosować do metod abstrakcyjnych, zmiennych lub konstruktorów.

// strictfp keyword can be applied on methods, classes and interfaces.

strictfp class A{}

strictfp interface M{}

class A{  
    strictfp void m(){}
} 


Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow