SemtexGirl

É uma garota dinâmica e de bom gosto, uma garota que explode, que não para e nem aceita um não como resposta.

Acessando os atributos de um objeto

O Java suporta dois tipos de atributos:

• Atributos de instância, no qual existe um para cada objeto que instanciamos;
• Atributos de classe, cada classe possui uma única cópia do atributo, independente do número de objetos instanciados a partir da classe. Podemos distingui-los pelo modificador static.

Acessando atributos de instância
O acesso a atributos de instancia é muito simples porem é preciso seguir a risca dois passos:

1. O primeiro é obter o fieldID do atributo que queremos acessar, o fieldID é uma variável do tipo jfieldID usada pelo JNI para referenciar um atributo de um objeto. Para consegui-lo usamos a função:

GetFieldID
Protótipo:

jfieldID GetFieldID(JNIEnv *env, jclass clazz, const char *name,
const char *sig);

2. Em seguida usamos uma função que nos permite pegar (get) o modificador do atributo a partir do seu jobject e seu fieldID.

GetField
Protótipo:

 GetField(JNIEnv *env,jobject obj,
jfieldID fieldID);

Como podem ver na tabela abaixo existe uma função GetField para cada tipo de dado.

Get<Tipo>Field <TipoNativo>
GetObjectField Jobject
GetBooleanField Jboolean
GetByteField Jbyte
GetCharField Jchar
GetShortField Jshort
GetIntField Jint
GetLongField Jlong
GetFloatField Jfloat
GetDoubleField Jdouble

Sendo que a primeira função da lista é para ler os atributos de objetos.
Existem também funções correspondentes para atribuirmos dados aos atributos (set):

SetField
Protótipo:

void Set<tipo>Field(JNIEnv *env, jobject obj, jfieldID fieldID,
<tipoNativo> value);
Set<Tipo>Field <TipoNativo>
SetObjectField Jobject
SetBooleanField Jboolean
SetByteField Jbyte
SetCharField Jchar
SetShortField Jshort
SetIntField Jint
SetLongField Jlong
SetFloatField Jfloat
SetDoubleField Jdouble

Para exemplificar, na listagem 4, faremos um método nativo em uma classe Java que incrementa o valor de um atributo da própria classe cada vez que o chamamos.

  1. /* Contador.java */
  2.  
  3. public class Contador {
  4. private int atributo = 0;
  5. private native void incrementa();
  6. public static void main(String[] args) {
  7. Contador contador = new Contador();
  8. System.out.println("Antes de chamar o método
  9. incrementa() o atributo vale:"+contador.atributo);
  10. contador.incrementa();
  11. System.out.println("Depois de chamar o método
  12. incrementa() o atributo vale:"+contador.atributo);
  13. }
  14.  
  15. static {
  16. System.loadLibrary("contador");
  17. }
  18. }
  19.  

Listagem 4: Contador.java

A implementação do método nativo correspondente pode ser visto na listagem 5:

  1.  
  2. /* contador.cpp */
  3.  
  4. #include <jni.h>
  5.  
  6. JNIEXPORT void JNICALL Java_Contador_incrementa(JNIEnv *env, jobject obj){
  7. jint valor;
  8. //Buscar a referencia de uma classe no objeto
  9. jclass class = (*env)->GetObjectClass(env,obj);
  10. jfieldID fieldID = (*env)->GetFieldID(env, class, "atributo","I");
  11. if(fieldID ==NULL)
  12. return;//gerar exception
  13. valor = (*env)->GetIntField(env, obj, fieldID);
  14. valor++;
  15. (*env)->SetIntField(env, obj, fieldID, valor);
  16. }
  17.  

Listagem 5: Contador.cpp

Observe que precisamos obter uma referência à classe do objeto, para tanto usamos a função:

GetObjectClass
Protótipo:

jclass GetObjectClass(JNIEnv *env, jobject obj);

Acessando atributos de classe

O acesso aos atributos de classe é parecido com o acesso aos atributos de instância porem para obtermos o fieldID usamos a função:

GetStaticFieldID
Protótipo:

jfieldID GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name,
const char *sig);

Depois para acessarmos o seu valor usamos a função:

GetStaticField
Protótipo:

 GetStaticField(JNIEnv *env, jclass clazz,
jfieldID fieldID);

E assim como no acesso aos atributos de instância, o acesso a atributos de classe também possui uma função para cada tipo de dado.

GetStatic<Tipo>Field <TipoNativo>
GetStaticObjectField Jobject
GetStaticBooleanField Jboolean
GetStaticByteField Jbyte
GetStaticCharField Jchar
GetStaticShortField Jshort
GetStaticIntField Jint
GetStaticLongField Jlong
GetStaticFloatField Jfloat
GetStaticDoubleField Jdouble

Todavia ao invés de receber um jobject as funções GetStaticField recebem um jclass. E também possui suas respectivas funções de atribuições de dados:

SetStaticField
Protótipo:

void SetStatic<tipo>Field(JNIEnv *env,jclass clazz, jfieldID fieldID,
<nativeType> value);
SetStatic<Tipo>Field <TipoNativo>
SetStaticObjectField Jobject
SetStaticBooleanField Jboolean
SetStaticByteField Jbyte
SetStaticCharField Jchar
SetStaticShortField Jshort
SetStaticIntField Jint
SetStaticLongField Jlong
SetStaticFloatField Jfloat
SetStaticDoubleField Jdouble
Comments are off for this post

Comments are closed.