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.
Related
I have an ManagerCLass, which includes many other Objects. Here are methodes, that takes thes Objects and call an method on theses Objects..
Example:
public class Manager extends BaseManager {
ClassA classA = new ClassA();
ClassB classB = new ClassB();
ClassC classC = new ClassC();
ClassD classD = new ClassD();
ClassE classE = new ClassE();
public void callMethodsOnObjects() {
classA.printResult();
classB.printResult();
classC.printResult();
classD.printResult();
classE.printResult();
}
}
These classes have all the same Superclass. Now my Question is, is there a way to automate the callMethodsOnObjects()-method?
My Idea was to get all declaredClasses of the Managerclass. Then to Loop of the array an excecute the printResult()-methode on each Object.
Class<?>[] classes = Manager.class.getDeclaredClasses();
for (int i = 0; i < classes.length; i++) {
....
}
But this donĀ“t work. The Array is Empty.
So do you have an Idea if this a way to automate this?
There are still more methods that are structured this way.
I'm not getting anywhere here. Does it make sense to do it this way, as I imagined it?
OK, so the real problem here is that you are using Java terminology incorrectly.
There are no member classes of the Manager class. Yup. That's what I said!
A "member class" is a class that is declared inside another class. But there aren't any classes declared inside Manager.
However, there are fields ("member fields") declared inside Manager; i.e. classA, classB and so on. And these fields have classes; i.e. ClassA, ClassB and so on.
If you want to find the member fields of a class, use the Class.getDeclaredFields() method. This will give you an array of Field objects.
You can then get each field's class by calling Field.getType() on it. Then you can use reflection to lookup the classses printResult() method and invoke it on the value in the respective fields of a target object.
Notes:
The Class returned by getType() could denote a primitive type or array type rather than a class. This Class will represent the erased type of the field.
If you want the Type as it was declared in the source code, use Field.getGenericType() instead.
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
Say I have a class, Bobject with an instance variable and method to retrieve it:
public class Bobject {
private int bInstVar;
public Bobject() {
bInstVar = 1;
}
getBInstVar() {
return bInstVar;
}
}
If I create a class Cobject representing an object that is an array of Bobject like so:
public class Cobject {
public Bobject[] cInstVar;
public Cobject() {
cInstVar = new Bobject[2]; //arbitrary array size for simplicity of the question
for (i = 0; i <= 2; i++;) {
cInstVar[i] = new Bobject();
}
}
}
If I have a main program that creates a Cobject and attempts to access methods of the references to the Bobjects stored in each element, I find that I have to first access the Cobject instance variable, cInstVar. This means cInstVar has to be public for main() to get at it without a method if main is outside of the package or class.
My question is, is there a way around doing this:?
Cobject c = new Cobject;
c.cObject1[0].getBInstVar();
Instead, I want to have an object that is an array of another class and get to that classes instance methods easier like so:
Cobject c = new Cobject;
c.getBInstVar(); // error says 'array required, but Cobject found'
I'm still pretty new to Java (and stackExchange) so please forgive me if anything I've presented is unclear. Thanks in advance!
As a general rule of thumb class variable should be declared as private and you should use getter and settle methods....
Meaning you will need to create a getter method in 'Cobject' to get the 'Bobject' object your after.... Then another getter/setter method to access any attributes there, or a method to manipulate any data
But yes, you could hard code a method that will go into the array and return what you ask for. Probably need an index parameter tho
you can create a getter method for Bobject[] in Cobject class
and then you can do c.getCObject1()[0].getBInstVar();
What I'm basically trying to do is invoke a method on an object whose class is written in a String and compiled through javax.tools.JavaCompiler
That part is "easy", I've used something similar to this: https://sites.google.com/site/malenkov/java/081217
However, the object I want to invoke a method on is a field in a different class also written in a String and compiled through JavaCompiler. What I have is:
MemoryClassLoader mcl1 = new MemoryClassLoader("Class1", Class1Content);
MemoryClassLoader mcl2 = new MemoryClassLoader("Class2", Class2Content);
Class c1 = mcl1.loadClass("Class1");
Class c2 = mcl2.loadClass("Class2");
Field f = c1.getDeclaredField("current"); //current should be of type Class2
Object obj = f.get(c2.newInstance()); //trying to cast the Field to type Class2 so I can invoke Class2 methods on it
Method m = c2.getDeclaredMethod("Class2Method");
System.out.println(m.invoke(obj));
Important code in Class1 (aka in String variable Class1Content):
Class1Content = "public MemoryClassLoader mcl = new MemoryClassLoader(\"" + "Class2" + "\", Class2Content);\n" +
"Class c = mcl.loadClass(\"" + "Class2" + "\");\n" +
"public Object current;\n" + //the object I will try to invoke a method on
"public Class1()throws Exception{\n" +
"Field f = c.getDeclaredField(\"initialState\");" + // initialState is the name of the field in Class2 I'm trying to have in Class1
"current = f.get(c.newInstance()); c.cast(current);\n" +
"}\n";
When I try to run the first block of code I get an exception at line Object state = f.get(c2.newInstance());
Exception in thread "main" java.lang.IllegalArgumentException: Can not
set java.lang.Object field Class1.current to Class2
Is there any way I can do what I'm trying to achieve or do I have to go back to the drawing board?
Thanks!
MemoryClassLoader extends ClassLoader, so your two classes are loaded with different ClassLoaders. Unless you have specified some relationship between the ClassLoaders, classes loaded by one will not be seen by the other. I would try modifying the MemoryClassLoader so that one instance can load both classes.
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);