Buscar..


Introducción

Los modificadores que no son de acceso no cambian la accesibilidad de las variables y los métodos, pero sí les proporcionan propiedades especiales .

final

final en Java puede referirse a variables, métodos y clases. Hay tres reglas simples:

  • la variable final no puede ser reasignada
  • El método final no puede ser anulado
  • la clase final no puede ser extendida

Usos

Buena práctica de programación

Algunos desarrolladores consideran una buena práctica marcar una variable final cuando puedas. Si tiene una variable que no debe cambiarse, debe marcarla como final.

Un uso importante de final palabra clave final si para los parámetros del método. Si desea enfatizar que un método no cambia sus parámetros de entrada, marque las propiedades como finales.

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

Esto enfatiza que el método de sumup no va a cambiar los ints .

Acceso a la clase interna

Si su clase interna anónima quiere acceder a una variable, la variable debe marcarse como final

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

Esta clase no compila, ya que el name la variable, no es final.

Java SE 8

Efectivamente las variables finales son una excepción. Estas son variables locales que se escriben una sola vez y, por lo tanto, podrían ser definitivas. Efectivamente, también se puede acceder a las variables finales desde clases anónimas.

variable final static

Aunque el código a continuación es completamente legal cuando final variable final foo no es static , en caso de static no compilará:

class TestFinal {
    private final static List foo;

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

La razón es, repitámoslo de nuevo, la variable final no puede ser reasignada . Como foo es estático, se comparte entre todas las instancias de la clase TestFinal . Cuando se crea una nueva instancia de una clase TestFinal , se invoca su constructor y, por lo tanto, foo se reasigna y el compilador no lo permite. Una forma correcta de inicializar la variable foo en este caso es:

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

o utilizando un inicializador estático:

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

final métodos final son útiles cuando la clase base implementa alguna funcionalidad importante que la clase derivada no debe cambiar. También son más rápidos que los métodos no finales, porque no hay un concepto de tabla virtual involucrado.

Todas las clases de envoltorio en Java son finales, como Integer , Long , etc. Los creadores de estas clases no querían que nadie pudiera, por ejemplo, extender Integer a su propia clase y cambiar el comportamiento básico de la clase Integer. Uno de los requisitos para hacer que una clase sea inmutable es que las subclases no pueden anular los métodos. La forma más sencilla de hacer esto es declarar la clase como final .

volátil

El modificador volatile se utiliza en la programación de múltiples hilos. Si declara que un campo es volatile , es una señal a los subprocesos que deben leer el valor más reciente, no uno almacenado en caché local. Además, se garantiza que volatile lecturas y escrituras volatile son atómicas (el acceso a un long o double no volatile no es atómico), lo que evita ciertos errores de lectura / escritura entre varios subprocesos.

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

estático

La palabra clave static se usa en una clase, método o campo para hacer que funcionen independientemente de cualquier instancia de la clase.

  • Los campos estáticos son comunes a todas las instancias de una clase. No necesitan una instancia para acceder a ellos.
  • Los métodos estáticos se pueden ejecutar sin una instancia de la clase en la que se encuentran. Sin embargo, solo pueden acceder a los campos estáticos de esa clase.
  • Las clases estáticas pueden ser declaradas dentro de otras clases. No necesitan una instancia de la clase en la que están para ser instanciados.
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

resumen

La abstracción es un proceso de ocultar los detalles de la implementación y mostrar solo la funcionalidad al usuario. Una clase abstracta nunca puede ser instanciada. Si una clase se declara como abstracta, el único propósito es que la clase se extienda.

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

sincronizado

El modificador sincronizado se usa para controlar el acceso de un método en particular o un bloque por varios subprocesos. Solo un hilo puede entrar en un método o un bloque que se declara como sincronizado. la palabra clave sincronizada funciona en el bloqueo intrínseco de un objeto, en el caso de un método sincronizado, los objetos actuales se bloquean y el método estático utiliza el objeto de clase. Cualquier hilo que intente ejecutar un bloque sincronizado debe adquirir primero el bloqueo del objeto.

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

transitorio

Una variable que se declara como transitoria no se serializará durante la serialización de objetos.

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

strictfp

Java SE 1.2

El modificador strictfp se usa para cálculos de punto flotante. Este modificador hace que la variable de punto flotante sea más consistente en múltiples plataformas y garantiza que todos los cálculos de punto flotante se realicen de acuerdo con los estándares IEEE 754 para evitar errores de cálculo (errores de redondeo), desbordamientos y subflujos en la arquitectura de 32 bits y 64 bits. Esto no se puede aplicar en métodos abstractos, variables o constructores.

// 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
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow