Java bytecode é o conxunto de instrucións da máquina virtual de Java (JVM), a linguaxe na que se compila o código fonte de Java e outros códigos compatibles con JVM. Cada instrución é representada por un só byte, por iso o nome bytecode, o que o converte nunha forma compacta de datos.

Debido á natureza do bytecode, un programa de bytecode de Java pódese executar en calquera máquina cunha JVM compatíbel, sen o longo proceso de compilar a partir do código fonte.

Java bytecode é utilizado en tempo de compilación, xa sexa interpretado por unha JVM ou compilado a código máquina mediante compilación xusto a tempo (JIT) e executado como unha aplicación nativa.

Como Java bytecode está deseñado para a compatibilidade e seguridade entre plataformas, unha aplicación de Java bytecode tende a executarse de forma consistente en varias configuracións de hardware e software.

Relación con Java En xeral, un programador de Java non necesita comprender Java bytecode, nin sequera ser consciente del. Con todo, como se suxire na revista IBM developerWorks, "Comprender o bytecode e que bytecode é probable que xere un compilador de Java axuda ao programador de Java do mesmo xeito que o coñecemento de ensamblador axuda ao programador de C ou C++".

Arquitectura do conxunto de instrucións O bytecode comprende varios tipos de instrucións, incluíndo a manipulación de datos, a transferencia de control, a creación e manipulación de obxectos e a invocación de métodoa, todos eles parte integral do modelo de programación orientada a obxectos de Java.

A JVM é tanto unha máquina de pila como unha máquina de rexistros. Cada marco para unha chamada de método ten unha "pila de operandos" e unha matriz de "variábeis locais".:2.6 A pila de operandos úsase para pasar operandos aos cálculos e para recibir o valor de retorno dun método chamado, mentres que as variables locais serven para o mesmo propósito que os rexistros e tamén se usan para pasar argumentos de métodos. O tamaño máximo da pila de operandos e da matriz de variables locais, calculada polo compilador, forma parte dos atributos de cada método. :4.7.3 Cada un pode ter un tamaño independente de 0 a 65535 valores, onde cada valor é de 32 bits. Os tipos long e double, que son de 64 bits, ocupan dúas variables locais consecutivas:2.6.1 (que non precisan estar aliñadas a 64 bits na matriz de variables locais) ou un valor na pila de operandos (pero cóntanse como dúas unidades na profundidade da pila).: 2.6.2 

Conxunto de instrucións Cada bytecode está composto por un byte que representa o opcode, xunto con cero ou máis bytes para operandos.: 2.11 

Dos 256 opcodes de bytes posibles, dende 2015, 202 están en uso (~79%), 51 están reservados para uso futuro (~20%), e 3 instrucións (~1%) están reservadas permanentemente para que as usen as implementacións de JVM.: 6.2 Dúas destas (impdep1 e impdep2) serven para proporcionar trampas para software e hardware específicos da implementación, respectivamente. A terceira úsase para que os depuradores implementen puntos de interrupción (breakpoints).

As instrucións divídense en varios grupos amplos:

Carga e almacenamento (por exemplo, aload_0, istore) Aritmetico-lóxicas (por exemplo, ladd, fcmpl) Conversión de tipo (por exemplo, i2b, d2i) Creación e manipulación de obxectos (new, putfield) Xestión da pila de operandos (por exemplo, swap, dup2) Transferencia de control (por exemplo, ifeq, goto) Invocación e retorno de métodos (por exemplo, invokespecial, areturn)

Tamén hai algunhas instrucións para unha serie de tarefas máis especializadas, como a xeración de excepcións, a sincronización, etc.

Moitas instrucións teñen prefixos e/ou sufixos que refiren aos tipos de operandos nos que operan.: 2.11.1 Son os seguintes: Prefixo/SufixoTipo de operandoiintegerllongsshortbbyteccharacterffloatddoubleareference Por exemplo, iadd sumará dous enteiros, mentres que dadd sumará dous doubles. As instrucións const, load e store tamén poden tomar un sufixo da forma _n, onde n é un número do 0 ao 3 para load e store. O n máximo para const varía segundo o tipo.

As instrucións const introducen un valor do tipo especificado na pila. Por exemplo, iconst_5 introduce un enteiro (valor de 32 bits) co valor 5 na pila, mentres que dconst_1 introduce un double (valor de coma flotante de 64 bits) co valor 1 na pila. Tamén hai un aconst_null, que envía unha referencia nula (null). O n para as instrucións load e store especifica o índice na matriz de variables locais desde onde cargar ou onde almacenar. A instrución aload_0 envía o obxecto da variable local 0 á pila (normalmente é o obxecto this). istore_1 almacena o número enteiro que está na parte superior da pila na variable local 1. Para as variables locais posteriores a 3, o sufixo elimínase e deben usarse operandos.

Exemplo Considere o seguinte código Java:outer: for (int i = 2; i < 1000; i++) { for (int j = 2; j < i; j++) { if (i % j == 0) continue outer;

System.out.println(i); }Un compilador de Java podería traducir o código Java anterior a bytecode do seguinte xeito, supoñendo que se puxese nun método:0: iconst_2 1: istore_1 2: iload_1 3: sipush 1000 6: if_icmpge 44 9: iconst_2 10: istore_2 11: iload_2 12: iload_1 13: if_icmpge 31 16: iload_1 17: iload_2 18: irem 19: ifne 25 22: goto 38 25: iinc 2, 1 28: goto 11 31: getstatic #84; // Field java/lang/System.out:Ljava/io/PrintStream; 34: iload_1 35: invokevirtual #85; // Method java/io/PrintStream.println:(I)V 38: iinc 1, 1 41: goto 2 44: return

Xeración A linguaxe máis común á que se dirixe a máquina virtual de Java producindo Java bytecode é Java. Orixinalmente só existía un compilador, o compilador javac de Sun Microsystems, o cal compila código fonte Java a bytecode Java; pero como todas as especificacións para o bytecode Java xa están dispoñibles, outras partes forneceron compiladores que producen bytecode Java.

Algúns exemplos doutros compiladores inclúen:

Compilador Eclipse para Java (ECJ) Jikes, compila de Java a bytecode Java (desenvolvido por IBM, implementado en C++) Espresso, compila de Java a bytecode Java (só Java 1.0) GNU Compiler for Java (GCJ), compila de Java a bytecode Java; tamén pode compilar a código máquina nativo e formou parte da GNU Compiler Colección (GCC) ata a versión 6.

Algúns proxectos proporcionan ensambladores Java para permitir escribir Java bytecode a man. O código ensamblador tamén pode ser xerado por máquinas, por exemplo, por un compilador dirixido a unha máquina virtual Java. Entre os ensambladores de Java máis destacados inclúense:

Jasmin, toma descricións de texto para as clases de Java, escritas nunha sintaxe simple similar á dun ensamblador usando o conxunto de instrucións da máquina virtual Java e xera un ficheiro de clase Java Jamaica, unha linguaxe de ensamblaxe de macros para a máquina virtual Java. A sintaxe de Java úsase para a definición de clases ou de interfaces. Os corpos dos métodos especifícanse usando instrucións de bytecode. Krakatau Bytecode Tools, contén actualmente tres ferramentas: un descompilador e desensamblador para ficheiros de clase de Java e un ensamblador para crear ficheiros de clase. Lila, un ensamblador e desensamblador para a máquina virtual Java.

Outros desenvolveron compiladores, para diferentes linguaxes de programación, dirixidos á máquina virtual Java, como:

ColdFusion JRuby e Jython, dúas linguaxes de scripting baseadas en Ruby e Python Apache Groovy, linguaxe de propósito xeral opcionalmente tipada e dinámica, con capacidades de tipado estático e compilación estática Scala, unha linguaxe de programación xeral de tipado seguro que admite programación funcional e programación orientada a obxectos JGNAT e AppletMagic, compilan da linguaxe Ada a Java bytecode Compiladores de C a bytecode Java Clojure, unha linguaxe de programación funcional, inmutable e de propósito xeral da familia Lisp cunha forte énfase na concorrencia Kawa, unha implementación da linguaxe de programación Scheme, tamén un dialecto de Lisp. MIDletPascal O código JavaFX Script compílase en bytecode Java Kotlin, unha linguaxe de programación de propósito xeral con tipado estático e inferencia de tipos O código fonte de Object Pascal compílase en bytecode Java usando o compilador Free Pascal 3.0+.

Execución Hoxe en día existen varias máquinas virtuais Java dispoñibles para executar Java bytecode, tanto produtos gratuítos como comerciais. Se non é desexable executar bytecode nunha máquina virtual, un desenvolvedor tamén pode compilar código fonte ou Java bytecode directamente a código máquina nativo con ferramentas como o GNU Compiler for Java (GCJ). Algúns procesadores poden executar Java bytecode de forma nativa. Estes procesadores denomínanse procesadores de Java.

Compatibilidade con linguaxes dinámicas A máquina virtual Java ofrece certa compatibilidade con linguaxes de tipo dinámico. A maior parte do conxunto de instrucións JVM existente ten tipado estático, no sentido de que as chamadas a métodos teñen as súas sinaturas verificadas no tempo de compilación, sen un mecanismo para adiar esta decisión ao tempo de execución ou para elixir o envío do método mediante un enfoque alternativo.

JSR 292 (Compatibilidade con linguaxes de tipo dinámico na plataforma Java) engadiu unha nova instrución invokedynamic no nivel de JVM, para permitir a invocación de métodos baseándose na comprobación dinámica de tipo (en lugar da instrución invokevirtual existente con tipo verificado estaticamente). A máquina Da Vinci é unha implementación prototipo de máquina virtual que aloxa extensións de JVM destinadas a soportar linguaxes dinámicas. Todas as JVM compatibles con JSE 7 tamén inclúen o código de operación invokedynamic.

Referencias

Véxase tamén Ligazóns externas

Especificación da máquina virtual Java de Oracle Linguaxes de programación para a máquina virtual Java Visualizador de bytecode: visor e depurador de bytecode (complemento gratuíto de Eclipse) AdaptJ StackTrace: depuración a nivel de bytecode con control total da pila, as variables locais e o fluxo de execución Unpacker de clases Java: complemento para Total Commander, permite abrir ficheiros de clase como arquivos comprimidos e ver campos e métodos como ficheiros. O bytecode pódese ver como texto usando F3

Categoría:Java (linguaxe de programación)