miércoles, 11 de mayo de 2022

66 - Definición de constantes en Java mediante la palabra clave final

 Hasta ahora hemos visto que cuando definimos un atributo su valor puede ser cambiado en cualquier momento. Hay situaciones que ciertos datos a almacenar se los debe inicializar y nunca más van a cambiar, en esos casos debemos emplear constantes.



Si sabemos el valor que debe almacenar la constante podemos definirla y asignarle el valor

Problema

Implementar una clase llamada Circulo. Definir una constante donde se debe almacenar el valor de PI (relación entre la longitud de una circunferencia y su diámetro). Además definir otro atributo donde almacenar el radio del círculo.
Al constructor debe llegar el radio y otro método debe retornar el perímetro.

Programa:

Ver video
public class Circulo {
    private final double PI = 3.14159265358979323846;
    private double radio;

    public Circulo(double radio) {
        this.radio = radio;
    }

    public double retornarPerimetro() {
        return 2 * PI * radio;
    }

    public static void main(String[] ar) {
        Circulo circulo1 = new Circulo(5);
        System.out.println(circulo1.retornarPerimetro());
    }
}

Como vemos para definir una constante le antecedemos al tipo de dato la palabra clave 'final':

    private final double PI = 3.14159265358979323846;

Una constante no puede variar su valor durante la ejecución del programa. Si intentamos asignarle otro valor se genera un error de compilación:

java constantes final

Una constante puede ser: private, public o protected (según nuestra necesidad)

Si no sabemos que valor se cargará en la constante hasta que procedamos a ejecutar el programa, la inicialización se deberá hacer obligatoriamente en el constructor de la clase. Veamos un ejemplo para ver su sintaxis.

Problema

Implementar una clase llamada CajaDeAhorro. Se debe almacenar el número de documento del titular y el monto depositado. Una vez que se carga el documento no permitir su cambio.
Plantear dos constructores uno que llegue el documento del titular y el monto a depositar, y un segundo constructor que solo llegue el documento

Programa:

Ver video
public class CajaDeAhorro {
	private final String documento;
	private float monto;

	public CajaDeAhorro(String documento, float monto) {
		this.documento = documento;
		this.monto = monto;
	}

	public CajaDeAhorro(String documento) {
		this.documento = documento;
		this.monto = 0;
	}

	public void imprimir() {
		System.out.println("Documento:" + documento + "  Saldo:" + monto);
	}

	public static void main(String[] args) {
		CajaDeAhorro caja1 = new CajaDeAhorro("21222333", 1000);
		CajaDeAhorro caja2 = new CajaDeAhorro("36454444");
		caja1.imprimir();
		caja2.imprimir();
	}
}

Como vemos definimos la constante llamada 'documento' pero no asignamos valor:

	private final String documento;

Esto nos obliga que en el constructor o los constructores se deba inicializar en forma obligatoria la constante 'documento':

	public CajaDeAhorro(String documento, float monto) {
		this.documento = documento;
		this.monto = monto;
	}

	public CajaDeAhorro(String documento) {
		this.documento = documento;
		this.monto = 0;
	}

En el caso que nos olvidemos de inicializar la constante en el constructor el compilador de Java nos lo informará:

java constantes sin inicializar final

Si bien nuestro programa funcionará perfectamente si no definimos a 'documento' como constante, el uso de esta característica del lenguaje nos puede evitar errores que en programas grandes pueden ser difíciles de encontrar.

Recordemos bien que no podemos asignar otro valor a una constante fuera del momento de declaración o del constructor, luego se genera un error sintáctico si codificamos:

    public void imprimir() {
        documento = "12345678"; //Error en tiempo de compilación
        System.out.println("Documento:" + documento + "  Saldo:" + monto);
    }

Definición de constantes estáticas

Podemos definir una constante con el modificador 'static', recordemos que con este modificador hace que se reserve espacio para la constante en forma independiente a que se creen o no instancias de dicha clase.

Si definimos una constante con el modificador 'static' estamos obligados a inicializar su valor cuando lo declaramos y no podemos hacerlo en el constructor.

Problema

Plantear una clase Persona con los atributos nombre y edad. Implementar un método que retorne si es mayor de edad (almacenar en una constante estática el valor 18 que representa la mayoría de edad)

Programa:

Ver video
public class Persona {
    private static final int MAYOREDAD = 18;
    private String nombre;
    private int edad;

    public Persona(String nombre, int edad) {
        this.nombre = nombre;
        this.edad = edad;
    }

    public void imprimir() {
        System.out.println(nombre + " " + edad);
    }

    public String retornarNombre() {
        return nombre;
    }

    public boolean esMayor() {
        if (edad >= MAYOREDAD)
            return true;
        else
            return false;
    }

    public static void main(String[] args) {
        Persona persona1 = new Persona("Juan", 23);
        if (persona1.esMayor())
            System.out.println("Es mayor de edad " + persona1.retornarNombre());
        else
            System.out.println("No es mayor de edad " + persona1.retornarNombre());
    }
}

No importa la cantidad de objetos de la clase Persona que se creen, solo se reserva un espacio para la constante entera llamada 'MAYOREDAD':

    private static final int MAYOREDAD = 18;

Depende si queremos acceder a la constante desde fuera de la clase debemos utilizar el modificador 'public' en lugar de private.

Constante local a un método.

En el caso que definamos una constante dentro de un método, la misma se debe inicializar en el mismo momento que se la declara, o antes que se la consulte:

public class EjemploConstantes {

    public static void main(String[] args) {
        final double PI = 3.14159265358979323846;
        final double radio;
        radio=20;
        double perimetro = 2 * PI * radio;
        System.out.println(String.format("El perímetro de un círculo de radio %s es %s", radio, perimetro));
    }
}

Ejemplos de constantes estáticas en las clases estándares de Java

Ver video

Existen clases en los paquetes que suministra Java que definen constantes.

Si necesitamos acceder al código fuente donde se define la constante debemos presionar la tecla 'Control' y presionar el botón izquierdo del mouse sobre la constante, luego se abre el archivo fuente con la declaración:

java constantes acceder de Eclipse a su declaración
  • La clase Math define 2 constantes públicas (es decir que las podemos acceder desde afuera de la clase):

        public static final double E = 2.7182818284590452354;
        public static final double PI = 3.14159265358979323846;
    

    Hay otras constantes pero al ser privadas no las podemos acceder desde fuera de la clase y no tiene sentido ni conocerlas (tiene una utilidad solo dentro de la clase Math):

        private static final double DEGREES_TO_RADIANS = 0.017453292519943295;
        private static final double RADIANS_TO_DEGREES = 57.29577951308232;
        private static final long negativeZeroFloatBits  = Float.floatToRawIntBits(-0.0f);
        private static final long negativeZeroDoubleBits = Double.doubleToRawLongBits(-0.0d);
    
  • La clase Integer define 4 constantes públicas:

        public static final int   MIN_VALUE = 0x80000000;
        public static final int   MAX_VALUE = 0x7fffffff;
        public static final int SIZE = 32;
        public static final int BYTES = SIZE / Byte.SIZE;
    

    Podemos imprimir el contenido de estas cuatro constantes con el siguiente código:

        public static void main(String[] args) {
            System.out.println(Integer.MAX_VALUE); // Mayor valor entero: 2147483647
            System.out.println(Integer.MIN_VALUE); // Menor valor entero: -2147483648
            System.out.println(Integer.SIZE);      // Número de bits que requiere un entero: 32
            System.out.println(Integer.BYTES);     // Número de bytes que requiere un entero: 4
        }

No hay comentarios:

Publicar un comentario