¿Por qué funciona este código Java? Compilador no se queja de cierre

Mi DialogFragment contiene un botón -inicialmente invisible- OK y un ListView de elementos que se pueden hacer clic. Cuando se hace clic en alguno de los elementos ListView, establezco la visibilidad del botón VISIBLE.

Esto se hace a través de un OnItemClickListener anónimo. El código de abajo funciona pero no entiendo por qué. Dado que Java no soporta cierres, espero que el compilador se queje de que el botón no sea definitivo.

¿No es este el caso típico de un cierre? ¿Por qué el código siguiente no produce un error de compilador?

Gracias

public class AlternativeRoomsDialog extends DialogFragment { private Button okButton; static AlternativeRoomsDialog newInstance(String name) { AlternativeRoomsDialog f = new AlternativeRoomsDialog(); return f; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_alternative_rooms, container); getDialog().setTitle("Change Room"); ListView lv = (ListView) view.findViewById(R.id.alternative_rooms_list); final adapter = /*some initialization*/; lv.setAdapter(adapter); lv.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> arg0, View linlay, int position, long id) { okButton.setVisibility(View.VISIBLE); ListView lv = (ListView) linlay.getParent(); int total = lv.getChildCount(); for (int i=0; i< total; i++){ lv.getChildAt(i).setBackgroundColor(Color.BLUE); } linlay.setBackgroundColor(Color.GREEN); } }); // setup OK button okButton = (Button) view.findViewById(R.id.btn_ok); okButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Toast.makeText(AlternativeRoomsDialog.this.getActivity(), "ok button clicked", Toast.LENGTH_SHORT).show(); } }); return view; } 

}

El requisito de que las variables sean declaradas finales sólo se aplica a las variables locales, ya que son las que salen del alcance cuando el método devuelve. Su botón está referenciado por una variable miembro, y no hay necesidad de que sea final: el miembro no irá a ninguna parte siempre y cuando el objeto exista.

No es necesario que la variable de instancia final , que es sólo el caso con las variables locales. Las variables locales deben ser final , se copian a la clase anónima que se utiliza dentro del método, como variables de instancia de esa clase. Esto se hace porque la instancia de clase interna anónima puede permanecer en memoria de montón, después de devuelve el método. Por lo tanto, puede requerir el acceso a la variable incluso después de que el marco de la pila del método se desasigna.

Ahora, puesto que hay 2 copias de las variables locales, pueden salir de la sincronización, si la variable local se cambia fuera de la clase interna anónima. Eso sería realmente extraño, por eso es necesario que la variable local final .

Al igual que con las variables de instancia , son compartidas entre la instancia de clase cerrada y la instancia de clase interna anónima. Por lo tanto, no es necesario que sean final .

  • Escribir objetos a los paquetes
  • Convertir cadena a Date en java
  • CSVReader y InputStream
  • Expresión regular de Android: devuelve la cadena correspondiente
  • El problema de la funcionalidad de solicitudes de espera en la biblioteca Volley (PriorityBlockingQueue.java)
  • Llamar a MediaRecorder bloquea la aplicación en AndroidStudio
  • YouTube API 3 Subir video - Acceso no configurado - Android
  • Cómo probar si el cursor está vacío en una consulta SQLiteDatabase
  • Libgdx extraño modelado - error de profundidad?
  • Persistencia de objetos con Realm (error: Cambiar datos de Realm sólo se puede hacer desde dentro de una transacción)
  • La tabla de resultados de Android no funciona después de que la publicación muestre RESULT_APP_MISCONFIGURED error
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.