Using reflection to invoke method on field - java

My code looks like the following:
class MyObject {
MyField f = new MyField();
}
class MyField {
public void greatMethod();
}
Is there a way to invoke the greatMethod() using reflection on a object of the class MyObject?
I tried the following:
Field f = myObject.getClass().getDeclaredField("f");
Method myMethod = f.getDeclaringClass().getDeclaredMethod("greatMethod", new Class[]{});
myMethod.invoke(f);
But instead it is trying to call greatMethod() on my myObject directly and not on the field f in it. Is there a way to achieve this without need to modify the MyObject class (so that it would implement a method which calls the appropriate method on f).

You were close yourself, you just need to get the declared method and invoke it on the instance of the field that is containted within your object instance, instead of the field, like below
// obtain an object instance
MyObject myObjectInstance = new MyObject();
// get the field definition
Field fieldDefinition = myObjectInstance.getClass().getDeclaredField("f");
// make it accessible
fieldDefinition.setAccessible(true);
// obtain the field value from the object instance
Object fieldValue = fieldDefinition.get(myObjectInstance);
// get declared method
Method myMethod =fieldValue.getClass().getDeclaredMethod("greatMethod", new Class[]{});
// invoke method on the instance of the field from yor object instance
myMethod.invoke(fieldValue);

Related

How to call a method in another class when the given classname is string

I have two classes in java. I am calling a method of 2nd class from 1st class when the 2nd class name is stored in a string variable.
I tried the below code.It creates the class.
String adapterClass = "com.appzillon.server.impl.ViewAccDtlsAdapterImpl";
Class className = Class.forName(adapterClass);
After that how to call the method.Method name is getInfo with a string type paramater.
Method method = className.getDeclaredMethod("getInfo", String.class);
method.invoke(instance, "your parameter");
Where instance is either:
Object instance = null;
if the method is static. Or:
Object instance = className.getDeclaredConstructor().newInstance();
If the method is a member method
For scenarios like these, you can very well use Java Reflection APIs.
Class classInstance = Class.forName(<your class name>);
Methoed methodHandle = classInstance.getMethod(<methodName>,<arguments classes>);
Object returnValue = methodHandle.invoke(null, "parameter-value1");
Note : The null parameter is the object you want to invoke the method on. If the method is static you supply null instead of an object instance

retrieve field of type class

I have a class that is going to be passed into a function and it will be defined as follows:
class ayy{
String blah;
Class a;
Class b;
}
I want to be able to invoke the getSimpleName() method on the classes a and b. Currently I am doing it as follows:
Class c = (Class)argument; // Where argument is the "ayy" class
c.getField("a").getSimpleName();
But this gives me an error saying "getSimpleName()" is not defined for type field.
You cannot call a method directly on an object that results from reflection, such as you're doing with Field, as if it were a reference variable of the desired type.
Instead, you'll need to call getDeclaredField, because getField only gets public fields. Also, you'll need to get() the value of the Field, passing in an instance of the ayy class, which will return the value of the Field. Then you'll need to cast it to a Class, because get() returns an Object. Then you can call getSimpleName().
Class<?> classOfA = (Class<?>) c.getDeclaredField("a").get(anAyy);
String simpleName = classOfA.getSimpleName();
You'll also need to catch the various reflection-related exceptions that may be thrown.

Dynamically creating and populating class inside method in java

Though my question seems repetition, but I am new to Reflections and could find solution to the exact problem.
I need to write a method, which any class can call to populate its data. For simplicity, I created a class say MappingHelper, with a Factory like method 'Create' which will create its own instance. I need to then populate this instance and return it.
public final Class MappingHelper{
public final Object getBENodeData(Class<?> classRef, String className){
Class myClass = Class.forName(classRef.getName());
Method method = classRef.getMethod("Create",(Class<?>[])null);
Object obj = method.invoke(null, (Object[]) null);
}
}
I need to typecast obj to same type as of 'classRef' so that I can call its instance methods.
Could someone help?
What you're trying to do is not possible with reflection and with your current setup. Even if you manage to cast the object to classRef, you wouldn't know what instance methods to call since getBENodeData presumably can take any type.
What you can do is call the method from a location where the type is known, and cast to it.
Object obj = getBENodeData(MyType1.class, MyType1.class.getName());
MyType1 myType1 = (MyType1) obj;
myType1.setId(..);
Object obj2 = getBENodeData(MyType2.class, MyType2.class.getName());
MyType2 myType2 = (MyType2) obj2;
myType2.setName(..);

ClassLoader getDeclaredField instance error

Why when i try to invoke the method i get:
java.lang.IllegalArgumentException: object is not an instance of declaring class
My code:
Class<?> tWCCamRes = tCLSLoader.loadClass("com.github.sarxos.webcam.WebcamResolution");
Field tVGA = tWCCamRes.getDeclaredField("VGA");
Method tMeth = tVGA.getDeclaringClass().getDeclaredMethod("getSize");
tMeth.invoke(tVGA, (Object[]) null); // Error
In theory I pass the object instance but it failed.
Thanks in advance :)
You're calling the method getSize(), using reflection, on an object of type Field (tVGA), instead of calling it on the value of this field, which is of type WebcamResolution.
Assuming that you really need to do this via reflection, the code should be:
Class<?> tWCCamRes = tCLSLoader.loadClass("com.github.sarxos.webcam.WebcamResolution");
Field tVGA = tWCCamRes.getDeclaredField("VGA");
Object vgaFieldValue = tVGA.get(null); // it's a static field, so the argument of get() can be null.
Method tMeth = tVGA.getDeclaringClass().getDeclaredMethod("getSize");
tMeth.invoke(vgaFieldValue);
You invoke the getSize method on the field tVGA, but the method is declared on com.github.sarxos.webcam.WebcamResolution.
If you want to invoke an instance method you have to pass the instance as the inovke method's first argument.
If the method doesn't take an argument like com.github.sarxos.webcam.WebcamResolution.getSize()
Just invoke it this way:
tMeth.invoke(webcamResolutionObj);
But why don't you just use the WebcamResolution enum.
String enumName = "VGA";
WebcamResolution wcResolution = WebcamResolution.valueOf(enumName);
Dimension size = wcResolution.getSize();

use variable as object name to call the object method

I have a class which contains a couple different objects.
I can use getDeclaredFields to get the name list of all objects,
but I want to call a method in these objects.
How can I do that?
ClassA a = new ClassA();
Class cls = c.getClass();
Field[] fields = cls.getDeclaredFields();
for(int i = 0; i< fields.length;i++) {
System.out.println("Field = " + fields[i].toString());
System.out.prontln(fields[i].method()) // how can I call the method from object fields[i]
}
more info: the reason I use reflection is I want write a test class which can be used to test all other classes' objects are properly existing.
testclass(class a), get all objects name in the class a, and use object.exists() method to verify the existing of this object.
here is my code: I have some dialog classes, each dialog class has some menuitem class, checkbox class,textfield class, I want write a class which can be used to verify all checboxes,textfields are exsting (use checkbox.exist(), textfield.exist() ...) in the given dialog.
ToolsMenu c = new ToolsMenu();
Class cls = c.getClass();
Field[] fields = cls.getDeclaredFields();
for(int i = 0; i< fields.length;i++) {
System.out.println("Field = " + fields[i].toString());
println( fields[i].getDeclaringClass().exists()
I can use getdeclaringclass to get the field[i] class, but how can i call method exists() which is defined in checkboxes,textfields class.
You can call it with something like this:
...
Class clazz= fields[i].get(c).getClass();
clazz.getMethod("methodName").invoke(fields[i].get(c));
...
Where "methodName" is name of the method which should be called. You can also pass some parameters to the method.
I'm not sure why you are using reflection at all. You can simply do
a.field.method()
If field and its method() declare the correct access modifiers.

Categories

Resources