Las funciones de acceso Java son funciones de sistema EGL que permiten al código Java generado acceder a objetos y clases Java nativos; concretamente, para acceder a los métodos, constructores y campos de tipo público del código nativo.
Esta característica de EGL se hace posible durante la ejecución gracias a la presencia del espacio de objetos Java EGL, que es un conjunto de nombres y los objetos a los que estos nombres hacen referencia. Un único espacio de objetos está disponible en el programa generado y en todo el código Java generado al que el programa llama localmente, tanto si las llamadas son directas o a través de otro programa Java generado local, en cualquier nivel de la llamada. El espacio de objetos no está disponible en ningún código Java nativo.
Para almacenar y recuperar objetos del espacio de objetos, invoque las funciones de acceso Java. Las invocaciones incluyen el uso de identificadores, cada uno de los cuales es una serie que se utiliza para almacenar un objeto o para que coincida con un nombre que ya existe en el espacio de objetos. Cuando un identificador coincide con un nombre, el código puede acceder al objeto asociado al nombre.
Cada uno de los argumentos pasados a un método (y cada valor asignado a un campo) se correlaciona con un objeto o tipo primitivo Java. Los elementos del tipo primitivo EGL CHAR, por ejemplo, se pasan como objetos de la clase Java String. Se suministra un operador de conversión temporal para las situaciones en las que la correlación de tipos EGL con tipos Java no es suficiente.
Si se especifica un nombre Java, EGL elimina blancos de un solo byte y de doble byte del principio y el final del valor, que es sensible a mayúsculas y minúsculas. El truncamiento precede a cualquier conversión temporal. Este norma se aplica a los literales de serie y a los elementos de tipo CHAR, DBCHAR, MBCHAR o UNICODE. Este tipo de truncamiento no se produce si se especifica un argumento de método o valor de campo (por ejemplo, la serie " mis datos " se pasa a un método sin cambios), a menos que convierta temporalmente el valor a objID o nulo.
La tabla siguiente describe todas las correlaciones válidas.
Categoría de argumento | Ejemplos | Tipo Java | |
---|---|---|---|
Un literal de serie o un elemento de tipo CHAR, DBCHAR, MBCHAR o UNICODE | Sin conversión temporal | "myString" |
java.lang.String |
Conversión temporal con objId, que indica un identificador | (objId)"myId" x = "myId"; (objId)X |
La clase del objeto al que el identificador hace referencia | |
Conversión temporal con null, que puede ser adecuado para proporcionar una referencia nula a una clase totalmente calificada | (null)"java. lang.Thread" x = "java.util. HashMap"; (null)x |
La clase especificada Nota: No puede pasarse una matriz convertida temporalmente con null, como por ejemplo (null)"int[]"
|
|
Conversión temporal con char, que significa que se pasa el primer carácter del valor (cada ejemplo de la columna siguiente pasa una "a") | (char)"abc" X = "abc"; (char)X |
char | |
Un elemento de tipo FLOAT o un literal de coma flotante | Sin conversión temporal | myFloatValue |
double |
Un elemento de tipo HEX | Sin conversión temporal | myHexValue |
matriz de bytes |
Un elemento de tipo SMALLFLOAT | Sin conversión temporal | mySmallFloat |
float |
Un elemento de tipo DATE | Sin conversión temporal | myDate |
java.sql.Date |
Un elemento de tipo TIME | Sin conversión temporal | myTime |
java.sql.Time |
Un elemento de tipo TIMESTAMP | Sin conversión temporal | myTimeStamp |
java.sql.Timestamp |
Un elemento de tipo INTERVAL | Sin conversión temporal | myInterval |
java.lang.String |
Literal de coma flotante | Sin conversión temporal | -6.5231E96 | double |
Elemento numérico (o literal de coma no flotante) que no contiene decimales; los ceros iniciales se incluyen en el número de dígitos para un literal | Sin conversión temporal, 1-4 dígitos | 0100 |
short |
Sin conversión temporal, 5–9 dígitos | 00100 |
int | |
Sin conversión temporal, 9-18 dígitos | 1234567890 |
long | |
Sin conversión temporal, > 18 dígitos | 1234567890123456789 |
java.math.BigInteger | |
Elemento numérico (o literales de coma no flotante) que contiene decimales; los ceros iniciales y finales se incluyen en el número de dígitos para un literal | Sin conversión temporal, 1–6 dígitos | 3.14159 |
float |
Sin conversión temporal, 7-18 dígitos | 3.14159265 |
double | |
Sin conversión temporal, > 18 dígitos | 56789543.222 |
java.math.BigDecimal | |
Elemento o literal de coma no flotante, con o sin decimales | Conversión temporal con bigdecimal, biginteger, byte, double, float, short, int, long | X = 42; (byte)X (long)X |
El tipo primitivo especificado; pero, si el valor está fuera de rango para ese tipo, se produce pérdida de precisión y el signo puede cambiar |
Conversión temporal con boolean, que significa que no cero es true, cero es false | X = 1; (boolean)X |
boolean |
Para obtener detalles acerca del formato interno de los elementos en EGL, consulte las páginas de la ayuda referentes a Tipos primitivos.
Esta sección ofrece ejemplos de utilización de funciones de acceso Java.
// llamar al constructor de la clase Java Date y // asignar el objeto nuevo al identificador "date". JavaLib.storeNew( (objId)"date", "java.util.Date" ); // llamar al método toString del objeto nuevo Date // y asignar la salida (fecha de hoy) a chaItem. // En ausencia de la conversión temporal (objId), "date" // hace referencia a una clase en lugar de a un objeto. charItem = JavaLib.invoke( (objId)"date", "toString" ); // asignar la corriente de salida estándar de la // clase Java System al identificador "systemOut". JavaLib.storeField( (objId)"systemOut", "java.lang.System", "out" ); // llamar al método println de la corriente de // salida e imprimir la fecha de hoy. JavaLib.invoke( (objID)"systemOut","println",charItem ); // La utilización de "java.lang.System.out" como primer // argumento en la línea anterior no habría sido // válida, ya que el argumento debe ser un // identificador que ya se encuentre en el espacio de objetos // o un nombre de clase. El argumento no puede hacer referencia a un campo estático.
// asignar el nombre de un identificador a un elemento de tipo CHAR valueID = "osNameProperty" // colocar el valor de la propiedad os.name en el // espacio de objetos, y relacionar ese valor (una serie Java) // con el identificador osNameProperty JavaLib.store((objId)valueId, "java.lang.System", "getProperty", "os.name"); // comprobar si el valor de propiedad no existe // y procesar de acuerdo con ello myNullFlag = JavaLib.isNull( (objId)valueId ); if( myNullFlag == 1 ) error = 27; end
Al trabajar con matrices Java en EGL, utilice la clase Java java.lang.reflect.Array, como se muestra en los ejemplos posteriores y se describe en la documentación de API Java. No puede utilizar JavaLib.storeNew para crear una matriz Java, ya que las matrices Java no tienen constructores.
Debe utilizar el método estático newInstance de java.lang.reflect.Array para crear la matriz en el espacio de objetos. Una vez creada la matriz, utilice otros métodos de esa clase para acceder a los elementos.
El código que identifica el objeto Class varía dependiendo de si se está creando una matriz de objetos o una matriz de primitivos. El código subsiguiente que interactúa con la matriz también varía sobre la misma base.
// Obtener una referencia a la clase, para utilizarla con newInstance JavaLib.store( (objId)"objectClass", "java.lang.Class", "forName", "java.lang.Object" ); // Crear la matriz en el espacio de objetos JavaLib.store( (objId)"myArray", "java.lang.reflect.Array", "newInstance", (objId)"objectClass", 5 );
Si desea crear una matriz que contenga un tipo de objeto diferente, cambie el nombre de clase que se pasa a la primera invocación de JavaLib.store. Para crear una matriz de objetos String, por ejemplo, pase "java.lang.String" en lugar de "java.lang.Object".
length = JavaLib.invoke( "java.lang.reflect.Array", "getLength", (objId)"myArray" ); i = 0; while ( i < length ) JavaLib.store( (objId)"element", "java.lang.reflect.Array", "get", (objId)"myArray", i ); // Aquí, procesar el elemento según convenga JavaLib.invoke( "java.lang.reflect.Array", "set", (objId)"myArray", i, (objId)"element" ); i = i + 1; end
int length = myArray.length; for ( int i = 0; i < length; i++ ) { Object element = myArray[i]; // Aquí, procesar el elemento según convenga myArray[i] = element; }
Para crear una matriz que almacene un primitivo Java en lugar de un objeto, utilice un mecanismo diferente en los pasos que preceden a la utilización de java.lang.reflect.Array. En particular, obtenga el argumento Class para newInstance accediendo al campo estático TYPE de una clase de tipo primitivo.
// Obtener una referencia a la clase, para utilizarla con newInstance JavaLib.storeField( (objId)"intClass", "java.lang.Integer", "TYPE"); // Crear la matriz en el espacio de objetos JavaLib.store( (objId)"myArray2", "java.lang.reflect.Array", "newInstance", (objId)"intClass", 30 );
Si desea crear una matriz que contenga un tipo de primitivo diferente, cambie el nombre de clase que se pasa a la primera invocación de JavaLib.storeField. Para crear una matriz de caracteres, por ejemplo, pase "java.lang.Character" en lugar de "java.lang.Integer".
length = JavaLib.invoke( "java.lang.reflect.Array", "getLength", (objId)"myArray2" ); i = 0; while ( i < length ) element = JavaLib.invoke( "java.lang.reflect.Array", "getDouble", (objId)"myArray2", i ); // Aquí, procesar un elemento según convenga JavaLib.invoke( "java.lang.reflect.Array", "setDouble", (objId)"myArray2", i, element ); i = i + 1; end
int length = myArray2.length; for ( int i = 0; i < length; i++ ) { double element = myArray2[i]; // Aquí, procesar un elemento según convenga myArray2[i] = element; }
Iterator contents = list.iterator(); while( contents.hasNext() ) { Object myObject = contents.next(); // Procesar myObject }
JavaLib.store( (objId)"contents", (objId)"list", "iterator" ); hasNext = JavaLib.invoke( (objId)"contents", "hasNext" ); while ( hasNext == 1 ) JavaLib.store( (objId)"myObject", (objId)"contents", "next"); // Procesar myObject hasNext = JavaLib.invoke( (objId)"contents", "hasNext" ); end
// Crear una colección a partir de la matriz myArray // y relacionar esa colección con el identificador "list JavaLib.store( (objId)"list", "java.util.Arrays", "asList", (objId)"myArray" );
A continuación, iterar sobre list, como se muestra en la sección anterior.
La transferencia de una matriz a una colección sólo funciona con una matriz de objetos, no con una matriz de primitivos Java. tenga cuidado de no confundir java.util.Arrays con java.lang.reflect.Array.
Muchas de las funciones de acceso Java están asociadas con códigos de error, como se describe en las páginas de la ayuda específicas de las funciones. Si el valor de la variable de sistema VGVar.handleSysLibraryErrors es 1 cuando se produce uno de los errores indicados, EGL establece la variable de sistema sysVar.errorCode en un valor no cero. Si el valor de VGVar.handleSysLibraryErrors es 0 cuando se produce uno de los errores, el programa finaliza.
Es de particular interés el valor de sysVar.errorCode "00001000", que indica que un método invocado ha lanzado una excepción o como resultado de una inicialización de clase.
Cuando se lanza una excepción, EGL la almacena en el espacio de objetos. Si se produce otra excepción, la segunda ocupa el lugar de la primera. Puede utilizar el identificador caughtException para acceder a la última excepción producida.
En una situación inusual, un método invocado lanza no una excepción, sino un error como, por ejemplo, OutOfMemoryError o StackOverflowError. En tal caso, el programa finaliza independientemente del valor de la variable de sistema VGVar.handleSysLibraryErrors.
int errorType = 0; Exception ex = null; try { java.io.FileOutputStream fOut = new java.io.FileOutputStream( "out.txt" ); } catch ( java.io.IOException iox ) { errorType = 1; ex = iox; } catch ( java.lang.SecurityException sx ) { errorType = 2; ex = sx; }
VGVar.handleSysLibraryErrors = 1; errorType = 0; JavaLib.storeNew( (objId)"fOut", "java.io.FileOutputStream", "out.txt" ); if ( sysVar.errorCode == "00001000" ) exType = JavaLib.qualifiedTypeName( (objId)"caughtException" ); if ( exType == "java.io.IOException" ) errorType = 1; JavaLib.storeCopy( (objId)"caughtException", (objId)"ex" ); else if ( exType == "java.lang.SecurityException" ) errorType = 2; JavaLib.storeCopy( (objId)"caughtException", (objId)"ex" ); end end end