Pasando clase anónima

Estoy pasando una interfaz como implementación anónima a un objeto diferente como este:

public interface Interface {
    public int convert (int a);
}



public static void main(String[] args) throws IOException, InterruptedException {

    final int[] array = {1,6,3,5,7,8,4,0,3};
    Interface inter = new Interface() {         
        public int convert(int a) {
            int result = a;             
            for (int i = 0; i < array.length; i++) {
                a=a+array[i];
            }               
            return a;
        }
    };

    SomeObject ty = new SomeObject ();
    ty.Test(7, inter);
}

public class SomeObject {   

    public void Test(int number, Interface inter) {             
        System.out.println(inter.convert(number));
    }
}

Mi pregunta es: ¿cómo funciona? Cómo SomeObjectsabe acerca de la matriz que no se pasa directamente al objeto (la matriz no es miembro de la clase anónima).

Actualización
(perdón por la actualización tardía)

¿Qué pasa con los métodos de miembros o métodos que se usan en la clase anónima? no son finales

Interface inter = new Interface() {         
    public int convert(int a) {
        int result = a + someMemberVar;             
        for (int i = 0; i < array.length; i++) {
            a=a+array[i];
        }               
        return a;
    }
};
Respuesta 1

Esto es parte de las reglas de alcance y visibilidad para Java. En su ejemplo actual se llama Cierre . Básicamente, todo lo que se define en un bloque es visible dentro de ese bloque. Por ejemplo, este es un código Java válido (en cualquier parte de un método):

{
    final int i = 5;
    // do somthing with i
}
// cant refernce i here
{
    final int i = 6;
    // do somthing with i
}
// cant refernce i here

Como define una nueva clase dentro del bloque (no funcionaría si solo la instanciara), ve todo lo declarado en el mismo bloque. El único límite que Java le impone es que no puede cambiar el valor después de la primera asignación, para evitar problemas cuando la referencia 'escapa' a su bloque (multiproceso, dura más que el bloque de declaración, etc.). Si declara que los parámetros del método son finales, también podría usarlos, ya que están definidos dentro del mismo bloque.

Entonces, si cambiaste tu código a esto

      {
          final int[] array = {1,6,3,5,7,8,4,0,3};
      }
      Object inter = new Object() 
      {           
          public void test() 
          {
              System.out.println(array);
          }
      };

No funcionaría (pruébalo).

Respuesta: 2

Está pasando la interfaz de objeto que tiene acceso a la matriz al método SomeObject.

Entonces SomeObject está utilizando la misma interfaz de objeto que pasó en main.

Como la interfaz tiene acceso a la matriz, es posible usarla.

No es SomeObject el que está usando la matriz. Es un objeto de interfaz.

Respuesta: 3

Java mantiene una referencia a todos los objetos (finales) de la clase envolvente utilizada en la clase interna. Si quieres saber cómo es este truco, agrega la siguiente línea al Método de prueba:

System.out.println(inter.getClass().getDeclaredConstructors()[0].getParameterTypes()[0].getCanonicalName()

Y su salida será "int []"

Entonces, el compilador simple crea un constructor para la clase interna y le pasa los campos que necesita

Respuesta: 4

Estoy probando la API de Amazon Device Messaging. Agregué el archivo jar usando la importación según lo sugerido por Amazon. Cuando despliegue en el dispositivo, aparece un error, 06-03 16: 24: 13.680: E / AndroidRuntime (11038): ...

Estoy tratando de crear un selector de archivo 'Guardar en'. Sin embargo, cuando ejecuto el código y presiono 'Abrir', se abre una nueva ventana de selección de archivos. El código: int val = jFileChooser1.showOpenDialog (nulo); privado ...

En una clase Java con campos de instancia estáticos, ¿se llama al constructor cada vez que se accede a los campos, o solo en el primer acceso? Inicializo los campos estáticos en el constructor, y estaba ...

Así que tengo alrededor de 4.000 documentos de palabras de los que intento extraer el texto e insertarlo en una tabla db. Esto funciona perfectamente hasta que el procesador encuentra un documento con la extensión de archivo * .doc ...