Tengo un rasgo Scala con un UUID público que tiene un valor por defecto:
trait pet {
var uuid_ : UUID = UUID.randomUUID
}
Ahora estoy creando múltiples clases, también en Scala:
class dog extends pet {
var foo = 1
}
class cat extends pet {
}
class fish extends pet {
}
Después de eso he creado un método en Java (proyecto de edad con dos idiomas mezclados).
Aquí el cortado con tijeras con mi problema. En la variable somePet
es una instancia de dog
, cat
o fish
. Sin embargo, no está claro cuál de ellos exactamente:
// printing all variables in the console for human testing
Serializer.printAllFields(somePet);
// The somePet Variable must be a pet
if(!pet.class.isAssignableFrom(somePet.getClass()))
throw new Exception("Not a pet.");
// get the UUID of the pet
UUID uuid_;
try {
Field f = pet.class.getField("uuid_");
f.setAccessible(true);
uuid_ = (UUID) f.get(somePet);
}catch(Exception e){
// no uuid found
throw e;
}
Pero cuando corro el código me sale el siguiente error:
Exception in thread "main" java.lang.NoSuchFieldException: uuid_
Y los puntos StackTrace en la línea con Field f = pet.class.getField("uuid_");
.
Pero lo que está mal con el código?
Un pensamiento alternativo que estaba reemplazando a esta línea exacta con:
Field f = ntObj.getClass().getField("uuid_");
Pero esto también falla.
Entonces, ¿dónde está la variable uuid_
?
Porque cuando imprimo todas las variables en la consola de la corriente somePet
con un Serializador, me sale algo como
* cat.uuid_ = 34d7a781-472d-4d98-861e-7cff08045445;
o
* dog.foo = 1
* dog.uuid_ = 34d7a781-472d-4d98-861e-7cff08045445;
en la consola.
Así que la variable uuid_
está allí con un valor por defecto.
(Estoy usando el serializador de este post )
Entonces, ¿cómo hago para que la uuid_
variable en mi fragmento de java?
En primer lugar, no hay tal Serializer
bajo el paquete java.util
, por lo que está usando otra cosa.
Una trait
se traduce a una aplicación Java interface
, que no pueden tener campos per se.
Sin embargo, usted está tratando de acceder al campo a través de la Pet
interfaz
pet.class.getField(...)
Eso no funcionará. Es necesario buscar el campo en el interior del hormigón class
.
Además, el campo será private
por defecto, ya que el acceso se concede a través de una getter
.
El getField
método es capaz de recuperar cada public
campo para toda la jerarquía de clases (que significa superclases incluso), mientras que getDeclaredField
es capaz de recuperar protected
y private
campos, pero sólo en la clase exacta que está llamando desde. Es necesario también un llamado a setAccessible(true)
, porque
El valor true indica que el objeto reflejado debe suprimir la comprobación de Java acceso al idioma cuando se utiliza. Un valor de false indica que el objeto reflejado debe hacer cumplir los controles de acceso del lenguaje Java
El código correcto sería ( dog
es el caso concreto)
final Field uuid = dog.getClass().getDeclaredField("uuid_");
uuid.setAccessible(true);
final Object o = uuid.get(dog);
O el uso de la automática getter
final Method uuid = dog.getClass().getMethod("uuid_");
final Object o = uuid_.invoke(dog);