Поиск…


Вступление

Модификаторы без доступа не изменяют доступность переменных и методов, но они предоставляют им особые свойства .

окончательный

final в Java может относиться к переменным, методам и классам. Существует три простых правила:

  • конечная переменная не может быть переназначена
  • окончательный метод нельзя переоценить
  • окончательный класс не может быть расширен

Обычаи

Хорошая практика программирования

Некоторые разработчики считают хорошей практикой отмечать переменную final, когда можете. Если у вас есть переменная, которая не должна быть изменена, вы должны отметить ее окончательную.

Важное использование final ключевого слова if для параметров метода. Если вы хотите подчеркнуть, что метод не меняет свои входные параметры, пометьте свойства как final.

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

Это подчеркивает, что метод sumup не собирается изменять ints .

Доступ к внутреннему классу

Если ваш анонимный внутренний класс хочет получить доступ к переменной, переменная должна быть отмечена final

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

Этот класс не компилируется, поскольку name переменной не является окончательным.

Java SE 8

Эффективно конечные переменные являются исключением. Это локальные переменные, которые записываются только один раз и поэтому могут быть сделаны окончательными. Эффективно конечные переменные можно получить и из классов анонимуса.

final static переменная

Несмотря на то, что приведенный ниже код полностью легален, когда final переменная foo не является static , в случае static она не будет компилироваться:

class TestFinal {
    private final static List foo;

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

Причина в том, что, повторим еще раз, конечная переменная не может быть переназначена . Поскольку foo является статическим, он разделяется между всеми экземплярами класса TestFinal . Когда создается новый экземпляр класса TestFinal , его конструктор вызывается и, следовательно, foo получает переназначение, компилятор которого не разрешает. Правильный способ инициализации переменной foo в этом случае:

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

или с помощью статического инициализатора:

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

final методы полезны, когда базовый класс реализует некоторые важные функции, которые производный класс не должен изменять. Они также быстрее, чем не конечные методы, потому что нет никакой концепции виртуальной таблицы.

Все классы-оболочки в Java являются окончательными, например Integer , Long и т. Д. Создатели этих классов не хотели, чтобы кто-либо мог, например, расширить Integer в свой класс и изменить основное поведение класса Integer. Одним из требований к созданию неизменяемого класса является то, что подклассы не могут переопределять методы. Самый простой способ сделать это - объявить класс final .

летучий

Модификатор volatile используется в многопоточном программировании. Если вы объявляете поле volatile это сигнал потокам, который должен прочитать последнее значение, а не локально кэшированное. Кроме того, volatile чтения и записи гарантированно являются атомарными (доступ к volatile long или double не является атомарным), что позволяет избежать некоторых ошибок чтения / записи между несколькими потоками.

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

статический

static ключевое слово используется для класса, метода или поля, чтобы заставить их работать независимо от любого экземпляра класса.

  • Статические поля являются общими для всех экземпляров класса. Им не нужен экземпляр для доступа к ним.
  • Статические методы могут выполняться без экземпляра класса, в котором они находятся. Однако они могут получить доступ только к статическим полям этого класса.
  • Статические классы могут быть объявлены внутри других классов. Им не нужен экземпляр класса, в котором они должны быть созданы.
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

Аннотация

Абстракция - это процесс скрытия деталей реализации и отображения пользователю только функциональных возможностей. Абстрактный класс никогда не может быть создан. Если класс объявлен как абстрактный, единственной целью является расширение класса.

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

синхронизированный

Синхронизированный модификатор используется для управления доступом определенного метода или блока несколькими потоками. Только один поток может входить в метод или блок, который объявляется как синхронизированный. синхронизированное ключевое слово работает на внутренней блокировке объекта, в случае синхронного метода блокировка текущих объектов и статический метод использует объект класса. Любой поток, пытающийся выполнить синхронизированный блок, должен сначала получить блокировку объекта.

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

преходящий

Переменная, объявленная как переходная, не будет сериализована во время сериализации объекта.

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

strictfp

Java SE 1.2

Для вычисления с плавающей запятой используется модификатор strictfp. Этот модификатор делает переменную с плавающей запятой более согласованной на нескольких платформах и гарантирует, что все вычисления с плавающей запятой выполняются в соответствии со стандартами IEEE 754, чтобы избежать ошибок вычисления (ошибки округления), переполнения и переполнения как на 32-битной, так и на 64-битной архитектуре. Это нельзя применить к абстрактным методам, переменным или конструкторам.

// 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
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow