2011-07-12 21 views
6

Estoy trabajando en un proyecto que utiliza la reflexión para obtener los campos de una aplicación Java en ejecución.Pregunta de reflexión de Java

Logré obtener los campos, pero no puedo leerlos ni escribir en ellos. Este es un ejemplo que encontré en la web:

Class aClass = MyObject.class 
Field field = aClass.getField("someField"); 
MyObject objectInstance = new MyObject(); 
Object value = field.get(objectInstance); 
field.set(objetInstance, value); 

El problema es que yo uso clases desde un archivo jar correr, y las clases que tratan de manipular se obtienen a partir del cargador de clases. Entonces, en lugar de 'MyObject.class', simplemente tengo '.class'. Para obtener el 'MyObject' traté de usar un ClassLoader pero eso no funcionó.

Si sólo tiene que utilizar' .class':

Object value = field.get(theLoadedClass); 

voy a conseguir este error:

java.lang.IllegalArgumentException: Can not set int field myClass.field to java.lang.Class 

Gracias.

+0

¿Qué quieres decir con 'a running jar file'? ¿Está en tu classpath? – wjans

Respuesta

0

Sus preguntas no son muy claras, pero creo que está preguntando cómo leer el valor de un campo de un objeto utilizando la reflexión.

Si mira en el JavaDoc de Field.get, verá que el argumento para Field.get debe ser la instancia del objeto del que está tratando de leer el campo (no el objeto Class). Por lo tanto, debe ser algo como:

Object value = field.get(someInstanceOfTheLoadedClass); 

You erros parece ser el resultado de tratar de asignar algo de tipo Class a un campo de tipo int. Debe usar Field.setInt para establecer campos int.

No importa si obtiene el objeto Clase utilizando .class o usando Class.forName.

+0

... o usando 'myObject.getClass()'. –

2

Necesita una instancia de la clase apropiada para pasar a los métodos field.get/set.

para obtener una instancia de un class puede probar estas opciones:

Class<?> clazz = MyObject.class; 
// How to call the default constructor from the class: 
MyObject myObject1 = clazz.newInstance(); 
// Example of calling a custom constructor from the class: 
MyObject myObject2 = clazz.getConstructor(String.class, Integer.class).newInstance("foo", 1); 
0

Si no conoce el tipo de uso del tiempo de compilación:

Class = objectInstance.getClass(); 

También como los otros críticos dijeron que tiene que saber qué tipo es el campo y usar el tipo correcto en consecuencia.

Para determinar este tiempo de ejecución use Field.getType() y use el getter y setter correcto después de eso.

3

Esto debería ayudar:

Class aClass = myClassLoader.loadClass("MyObject"); // use your class loader and fully qualified class name 
Field field = aClass.getField("someField"); 
// you can not use "MyObject objectInstance = new MyObject()" since its class would be loaded by a different classloader to the one used to obtain "aClass" 
// instead, use "newInstance()" method of the class 
Object objectInstance = aClass.newInstance(); 
Object value = field.get(objectInstance); 
field.set(objetInstance, value); 
2

De la documentación: java.lang.IllegalArgumentException se lanza:

If, after possible unwrapping, the new value cannot be converted to the type of the underlying field by an identity or widening conversion, the method throws an IllegalArgumentException.

Esto significa que el tipo de objeto (objeto) se intenta establecer el campo para no se puede convertir al tipo real. Intenta no usar un objeto allí.

no relacionado, mirando a su código que cambiaría la pieza

Class aClass = MyObject.class; 

a:

Class aClass = Class.forName("fullyQualifiedMyObjectClassName.e.g.com.bla.bla.MyObject"); 
0

hace este trabajo?

Class aClass = MyObject.class; 
Field field = aClass.getDeclaredField("someField"); 
field.setAccessible(true); 
MyObject objectInstance = new MyObject(); 
Object value = field.get(objectInstance); 
field.set(objectInstance, value);