Java Language
Modificadores sin acceso
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.
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
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(){}
}