sirve settitle que para java class jvm opcode

settitle - ¿Cuál es el propósito del indicador de acceso ACC_SUPER en los archivos de Java Class?



para que sirve settitle en java (1)

La instrucción de invokespecial JVM se usa para llamar a los métodos de inicialización ( <init> ) al crear nuevos objetos. La descripción de la instrucción sugiere (pero no aclara) que la decisión de llamar al constructor de una superclase o un constructor de la clase actual depende del estado del conjunto de indicadores ACC_SUPER dentro del archivo de class .

De la especificación de Sun JVM:

A continuación, el método resuelto se selecciona para invocación a menos que se cumplan todas las condiciones siguientes:

  • El indicador ACC_SUPER (consulte la Tabla 4.1, "Acceso a clase y modificadores de propiedad") se establece para la clase actual.

- Source ( invokespecial definición del código de operación especial)

La configuración del indicador ACC_SUPER indica cuál de las dos semánticas alternativas para sus instrucciones especiales de invocación debe expresar la máquina virtual Java; el indicador ACC_SUPER existe para la compatibilidad con versiones anteriores del código compilado por los compiladores más antiguos de Sun para el lenguaje de programación Java. Todas las nuevas implementaciones de la máquina virtual Java deben implementar la semántica para invocaciones especiales documentadas en esta especificación. Todos los compiladores nuevos para el conjunto de instrucciones de la máquina virtual Java deben establecer el indicador ACC_SUPER. Los compiladores más antiguos de Sun generaron marcas de ClassFile con ACC_SUPER no establecido. Las implementaciones de máquinas virtuales Java más antiguas de Sun ignoran el indicador si está configurado.

- Source (formato ClassFile )

La definición establece que la bandera es para compatibilidad con versiones anteriores de compiladores antiguos. Sin embargo, va en contra Sun''s older Java virtual machine implementations ignore the flag if it is set.

¿Se sigue utilizando la bandera con el invokespecial operación especial de invokespecial ? Por lo que puedo decir, parece no tener ningún propósito y no puedo encontrar un recurso para sugerir que alguna vez lo hizo.

Gracias.


Se introdujo ACC_SUPER para corregir un problema con la invocación de los súper métodos. El indicador ACC_SUPER marca una clase como compilada para la semántica cambiada de la instrucción opcode 183. Su propósito es similar al del número de versión del archivo de clase, ya que permite que la JVM detecte si una clase se compiló para la semántica más antigua o más nueva de esa instrucción. Java 1.0.2 no estableció e ignoró ACC_SUPER, mientras que Java 1.1 y posterior siempre establece ACC_SUPER.

Antes de Java 1.1, la instrucción de código de byte con código de operación 183 que ahora se llama invokespecial se llamaba invokenonvirtual y tenía una especificación parcialmente diferente. Se usaba siempre que los métodos de instancia debían invocarse sin una búsqueda de método virtual. Este fue el caso de los métodos privados, inicializadores de instancia (constructores) y para implementar invocaciones de métodos en super . Pero el último caso causó problemas con la evolución de las bibliotecas de clases.

Una referencia de método en el código de byte ( CONSTANT_Methodref_info ) no solo define el nombre y los tipos de argumento y retorno de un método, sino también la clase a la que pertenece. Opcode 183 obtiene dicho parámetro de referencia de método y estaba destinado a invocar directamente el método de referencia de la clase especificada sin más búsquedas. En el caso de invocaciones en super , fue responsabilidad de los compiladores resolver la súper clase más cercana que implementa este método y generar una referencia a él en el código de byte.

Desde que se cambió Java 1.1, esencialmente se ignora la clase a la que se hace referencia en CONSTANT_Methodref_info y, en su lugar, se realiza la búsqueda del super método más cercano con el nombre y la firma del método dado en la JVM. Esto generalmente se hace ahora cuando la clase se carga o justo antes de que se ejecute la instrucción o se compile JIT la primera vez.

Aquí hay un ejemplo de por qué este cambio fue necesario. En Java 1.0.2, las clases AWT Contenedor y Componente se definieron de esta manera:

class Component { public void paint( Graphics g ) {} } class Container extends Component { // inherits paint from Component but doesn''t override it }

En Java 1.1, la clase Conatiner se cambió para tener su propia implementación de paint :

class Container extends Component { public void paint( Graphics g ) {/*...*/} }

Ahora, cuando tenía una subclase directa o indirecta de Container que hacía una llamada en super.paint(g) y la compilaba para 1.0.2, generaba una instrucción invokenonvirtual para Component.paint ya que este era el primer padre que tenía este método. Pero si usó esta clase compilada en una JVM que también tenía Container.paint , todavía habría llamado Component.paint que no es lo que usted esperaría.

Por otro lado, cuando compilaste la clase para 1.1 y la ejecutaste en una JVM 1.0.2, lanzaría un AbstractMethodError o, más probablemente, para máquinas virtuales de esa era, simplemente fallaría. Para evitar el bloqueo, tuvo que escribir ((Component)super).paint(g) y compilarlo con un compilador 1.1 para obtener el comportamiento deseado en cualquiera de las ((Component)super).paint(g) . Esto establecería ACC_SUPER pero aún así generaría la instrucción para llamar a Component.paint . Una VM 1.0.2 ignoraría ACC_SUPER e iría directamente a invocar Component.paint que está bien, mientras que una VM 1.1 encontraría el conjunto ACC_SUPER y, por lo tanto, realizaría la búsqueda misma, lo que haría que invocara Container.paint , aunque la referencia del método del código de byte era Component.paint .

Puede encontrar más información sobre esto en este post anterior en el weblog ikvm.net .