Clases Internas Locales en Java

POO

Las clases internas locales son las clases internas que se definen dentro de un bloque. Generalmente, este bloque es un cuerpo de método. A veces, este bloque puede ser un ciclo for, o una cláusula if.

Lectura Recomendada
Clases Internas

1. Clases Locales

Las clases locales internas no son miembros de ninguna clase adjunta. Pertenecen al bloque en el que están definidos, debido a que las clases internas locales no pueden tener ningún modificador de acceso asociado. Sin embargo, se pueden marcar como final o abstract. Estas clases tienen acceso a los campos de la clase que lo encierra. La clase interna local debe crearse una instancia en el bloque en el que están definidas.

1.1. Reglas de clase una interna local

  1. El alcance de la clase interna local está restringido al bloque en el que está definidos.
  2. La clase interna local no se puede ser instanciado desde fuera del bloque donde se creó.
  3. Hasta JDK 7, la clase interna local solo puede acceder a la variable local final del bloque envolvente . Sin embargo, a partir de JDK 8, es posible acceder a la variable local no final del bloque delimitador en la clase interna local.
  4. Una clase local tiene acceso a los miembros de su clase adjunta.
  5. Las clases internas locales pueden extender una clase abstracta o también pueden implementar una interfaz.

Ya no es obligatorio ‘final’, siempre y cuando la variable no se modifique.

1.2. Declarar una clase interna local

Una clase interna local se puede declarar dentro de un bloque. Este bloque puede ser un cuerpo de método, bloque de inicialización, bucle for o incluso una sentencia if.

1.3. Acceso a los miembros

Una clase interna local tiene acceso a los campos de la clase que lo incluye, así como a los campos del bloque en el que está definido. Sin embargo, estas clases pueden acceder a las variables o parámetros del bloque que lo incluye solo si se declaran como definitivas o si son efectivamente finales. Una variable cuyo valor no se cambia una vez inicializada se denomina como variable final. Una clase interna local definida dentro de un cuerpo de método tiene acceso a sus parámetros.

1.4. ¿Qué sucede en el momento de la compilación?

Cuando se compila un programa que contiene una clase interna local, el compilador genera dos archivos .class, uno para la clase externa y el otro para la clase interna que tiene la referencia a la clase externa. Los dos archivos son nombrados por el compilador como:

Externa.class
Externa$1Interna.class

2. Clase interna local dentro de un método

Ejemplo:

// Programa Java para ilustrar el funcionamiento
// de las clases internas locales

//Clase externa
class ClaseExterna
{
    private void getValor() {
        //Tenga en cuenta que la variable local (suma) debe ser final --hasta JDK 7
        // por lo tanto, este código solo funcionará en JDK 8
        int suma = 20;

        //Método dentro de clase interna interna
        class Interna {
            private int divisor;
            private int resto;

            public Interna() {
                divisor = 4;
                resto = suma & divisor;
            }

            private int getDivisor(){
                return divisor;
            }

            private int getResto(){
                return suma%divisor;
            }

            private int getCociente(){
                System.out.println("Dentro de la clase local.");
                return suma/divisor;
            }
        }

        Interna interna=new Interna();
        System.out.println("Divisor: "+interna.getDivisor());
        System.out.println("Resto: "+interna.getResto());
        System.out.println("Cociente: "+interna.getCociente());
    }

    public static void main(String[] args) {
        ClaseExterna externa=new ClaseExterna();
        externa.getValor();
    }
}

Salida:

Divisor: 4
Resto: 0
Dentro de la clase local.
Cociente: 5
Nota: Una clase local puede acceder a variables y parámetros locales del bloque envolvente que son efectivamente finales. 

Una variable o parámetro cuyo valor nunca se cambia después de que se inicializa es efectivamente final.

Por ejemplo, si agrega la instrucción suma = 50; en el constructor de clase interna o en cualquier método de clase interna en el ejemplo anterior:

public Interna()
{
       suma = 50;
       divisor = 4;
       resto = sum%divisor;
}

Debido a esta declaración de asignación, la variable suma ya no es efectivamente final. Como resultado, el compilador de Java genera un mensaje de error similar a “las variables locales a las que se hace referencia desde una clase interna deben ser finales o efectivamente finales“.

3. Clase interna local dentro de una declaración if

Ejemplo:

// Programa Java para ilustrar el funcionamiento
// de las clases internas locales dentro de una declaración if

//Clase externa
class ClaseExterna
{
   public int dato=10;

   public int getDato(){
       return dato;
   }

    public static void main(String[] args) {
        ClaseExterna externa=new ClaseExterna();

        if (externa.getDato()<20){
            // Clase interna local dentro de la cláusula if
            class Interna{
                public int getValor(){
                    System.out.println("Dentro de la clase interna.");
                    return externa.dato;
                }
            }

            Interna interna=new Interna();
            System.out.println(interna.getValor());
        }
        else {
            System.out.println("Dentro de la clase externa.");
        }
    }
}

Salida:

Dentro de la clase interna.
10

4. Demostrando códigos erróneos para la clase interna

Ejemplo:

// Programa Java para demostrar
// que las clases internas no pueden ser declarados como static

//Clase externa
public class ClaseExterna
{
    private int getValor(int dato)
    {
        static class Interna
        {
            private int getDato()
            {
                System.out.println("Dentro de la clase interna.");
                if(dato < 10)
                {
                    return 5;
                }
                else
                {
                    return 15;
                }
            }
        }

        Interna interna = new Interna();
        return interna.getDato();
    }

    public static void main(String[] args)
    {
        ClaseExterna externa = new ClaseExterna();
        System.out.println(externa.getValor(10));
    }
}

Salida:

Compilation error

Explicación: El programa anterior causa un error de compilación porque la clase interna no se puede declarar como static. Las clases internas están asociadas con el bloque en el que están definidas y no con la clase externa (ClaseExterna en este caso).

Ejemplo:

// Programa Java para demostrar
// el alcance de la clase interna

//Clase externa
public class ClaseExterna
{
    private void miMetodo(){
        class Interna{
            private void metodoInterno(){
                System.out.println("Dentro de la clase interna.");
            }
        }
    }

    public static void main(String[] args) {
        ClaseExterna externa= new ClaseExterna();
        Interna interna=new Interna();
        System.out.println(interna.metodoInterno());
    }
}

Salida:

Compilation error

Explicación: El programa anterior causa un error de compilación porque el alcance de las clases internas está restringido al bloque en el que están definidas.

Clases Anidadas
  • Clases Internas locales

Sobre el Autor:

Hey hola! Yo soy Alex Walton y tengo el placer de compartir conocimientos hacía ti sobre el tema de Programación en Java, desde cero, Online y Gratis.

1 comentario

  1. Green-Screen Girl

    Hola Alex! Las clases internas me traen de cabeza (internas, anónimas y locales). Puedo entender la mecánica de como funcionan, pero no veo su razón de ser. Como forma de organizar el código lo veo “casi” retorcido. No veo como una función o bucle puede ser legible con una clase ahí en medio… (intento aplicar CleanCode en mis programas) Probablemente esto tenga que ver con mi inexperiencia. Me puedes recomendar alguna lectura, ejemplo … que se yo?! por donde cojo el tema.
    Muchas gracias por todos tus artículos, me están ayudando un montón!

Deja una Respuesta

*

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.