Reflection Generic Get Field Value

Reflection generic get field value

Like answered before, you should use:

Object value = field.get(objectInstance);

Another way, which is sometimes prefered, is calling the getter dynamically. example code:

public static Object runGetter(Field field, BaseValidationObject o)
{
// MZ: Find the correct method
for (Method method : o.getMethods())
{
if ((method.getName().startsWith("get")) && (method.getName().length() == (field.getName().length() + 3)))
{
if (method.getName().toLowerCase().endsWith(field.getName().toLowerCase()))
{
// MZ: Method found, run it
try
{
return method.invoke(o);
}
catch (IllegalAccessException e)
{
Logger.fatal("Could not determine method: " + method.getName());
}
catch (InvocationTargetException e)
{
Logger.fatal("Could not determine method: " + method.getName());
}

}
}
}

return null;
}

Also be aware that when your class inherits from another class, you need to recursively determine the Field. for instance, to fetch all Fields of a given class;

    for (Class<?> c = someClass; c != null; c = c.getSuperclass())
{
Field[] fields = c.getDeclaredFields();
for (Field classField : fields)
{
result.add(classField);
}
}

How to get field value in Java reflection

You can use:

String value = (String) this.getClass().getDeclaredField("str").get(this);

Or in a more generalized and safer form:

Field field = anObject.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
String value = (String) field.get(anObject);

And for your example, this should be enough:

String value = this.str; 

But you probably know of that one.

Note: anObject.getClass().getDeclaredField() is potentially unsafe as anObject.getClass() will return the actual class of anObject. See this example:

Object anObject = "Some string";
Class<?> clazz = anObject.getClass();
System.out.println(clazz);

Will print:

class java.lang.String

And not:

class java.lang.Object

So for your code's safety (and to avoid nasty errors when your code grows), you should use the actual class of the object you're trying to extract the field from:

Field field = YourObject.class.getDeclaredField(fieldName);

Get field values using reflection

Something like this...

import java.lang.reflect.Field;

public class Test {
public static void main(String... args) {
try {
Foobar foobar = new Foobar("Peter");
System.out.println("Name: " + foobar.getName());
Class<?> clazz = Class.forName("com.csa.mdm.Foobar");
System.out.println("Class: " + clazz);
Field field = clazz.getDeclaredField("name");
field.setAccessible(true);
String value = (String) field.get(foobar);
System.out.println("Value: " + value);
} catch (Exception e) {
e.printStackTrace();
}
}
}

class Foobar {
private final String name;

public Foobar(String name) {
this.name = name;
}

public String getName() {
return this.name;
}
}

Or, you can use the newInstance method of class to get an instance of your object at runtime. You'll still need to set that instance variable first though, otherwise it won't have any value.

E.g.

Class<?> clazz = Class.forName("com.something.Foobar");
Object object = clazz.newInstance();

Or, where it has two parameters in its constructor, String and int for example...

Class<?> clazz = Class.forName("com.something.Foobar");
Constructor<?> constructor = clazz.getConstructor(String.class, int.class);
Object obj = constructor.newInstance("Meaning Of Life", 42);

Or you can interrogate it for its constructors at runtime using clazz.getConstructors()

NB I deliberately omitted the casting of the object created here to the kind expected, as that would defeat the point of the reflection, as you'd already be aware of the class if you do that, which would negate the need for reflection in the first place.

Setting annotated field value using reflection in generic class. (IllegalArgumentException)

Here's your problem…

...
field.set(myValue, instance);
...

Here's your fix

...
field.set(instance, myValue);
...

Here are the docs

public void set​(Object obj, Object value)

...

Parameters:

obj - the object whose field should be modified

value - the new value for the field of obj being modified

Reflection - getting private field value

val currentTrainingField = viewModel.javaClass.getDeclaredField("currentTraining")
currentTrainingField.isAccessible = true

val currentTraining = currentTrainingField.get(viewModel)

You relaxed the field's scope but you should access the value of that field on a specfic object, here viewModel.

Obtain generic type of a Field using reflection

You have to check if the field is a ParameterizedType, and then inspect the contents of getActualTypeArguments, e.g.

    for (Field field : Ideone.class.getDeclaredFields()) {
Type type = field.getGenericType();
if (type instanceof ParameterizedType) {
ParameterizedType ptype = (ParameterizedType) type;
if (ptype.getRawType() == ScheduledView.class) {
if (ptype.getActualTypeArguments().length == 1
&& ptype.getActualTypeArguments()[0] == WantedClass.class) {
// Do whatever with the field.
System.out.println(field.getName());
}
}
}
}

Ideone demo

Java reflection: how to get field value from an object, not knowing its class

Assuming a simple case, where your field is public:

List list; // from your method
for(Object x : list) {
Class<?> clazz = x.getClass();
Field field = clazz.getField("fieldName"); //Note, this can throw an exception if the field doesn't exist.
Object fieldValue = field.get(x);
}

But this is pretty ugly, and I left out all of the try-catches, and makes a number of assumptions (public field, reflection available, nice security manager).

If you can change your method to return a List<Foo>, this becomes very easy because the iterator then can give you type information:

List<Foo> list; //From your method
for(Foo foo:list) {
Object fieldValue = foo.fieldName;
}

Or if you're consuming a Java 1.4 interface where generics aren't available, but you know the type of the objects that should be in the list...

List list;
for(Object x: list) {
if( x instanceof Foo) {
Object fieldValue = ((Foo)x).fieldName;
}
}

No reflection needed :)



Related Topics



Leave a reply



Submit