I'm not sure how "getDeclaredMethod" works in java, can some one explain how to get the value from the method, this is what i have..
I want to get this value (body_number), which is in the AIBody Class.
public int getBody_number() {
return body_number;
}
And in the same class i have this
Method m = body_A.getUserData().getClass().getDeclaredMethod("getBody_number", null);
How would i get the "body_number" value from m?
ps getUserData is a class of the object that i want to get the method answer out of
Any help would be great.
Adam
Since m is an instance method of whatever object is returned by body_A.getUserData() and it takes no arguments, you'd do something like this:
Method m = body_A.getUserData().getClass().getDeclaredMethod(
"getBody_number", null
);
int val = (Integer) m.invoke(body_A.getUserData());
(You'll have to wrap it in a try/catch or declare the appropriate throws in the method in which this code executes.)
Of course, once you have the Method object, you are not limited to invoking it for the object returned by body_A.getUserData(); you can pass it any instance of AIBody.
Reference: Method.invoke() doc
However, I have to agree with what Bhaskar wrote: why are you using reflection for this? You can simply call:
int val = body_A.getUserData().getBody_number();
You get back an instance of java.lang.reflect.Method, on which you use the invoke method
int val = ((Integer)m.invoke(body_A.getUserData())).intValue()
You may want to consider why you are using reflection in this case and not just
body_A.getUserData().getBody_number()
Related
I am trying to figure out how to invoke a method of a custom class. Here is the process of what I am trying to do:
1) I initialize an array of methods from the list of methods of my custom class, and an empty List of Method which will be used to hold a filtered list of these methods.
Method method[] = MyClass.getDeclaredMethods();
List<Method> x = new ArrayList<Method>();
2) I then run my array of methods through a for loop and filter out whichever methods do not fill my required criteria.
for (Method m : methods){
if(...){
if(...){
x.add(m);
}
}
}
3) Finally, I need to invoke each of the methods in the finalized list. This is where I am stuck, I am not exactly sure how the invoke function works. Here is what I am trying:
for(int i=0; i < x.size(); i++){
boolean g = x.get(i).invoke();
if(...)
else(...)
}
The thing is, I know Exactly what it is I don't know, I am just having trouble finding the answers. These are the questions I need answered:
1) Which object will actually use the invoke function? Is it going to be, in my case, the particular method I want to invoke, or an instance of the class I am trying to invoke?
2) I know that the invoke function is going to require arguments, one of which is the parameter data for the method. What I am unclear about is what exactly the first argument needs to be. I am thinking that the first argument is the actual method itself, but then I run into a logical loop, because the way I have it coded has the method using the invoke function, so I am stumped.
3) In my case, the methods I wish to invoke don't actually take any parameters, so when I do happen to figure out how the invoke function works, will I need to set one of the arguments to null, or will I just omit that part of the argument list?
You're using .invoke incorrectly. See this short example:
public class Test {
public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
X obj = new X();
Method method = obj.getClass().getMethod("test", null);
method.invoke(obj, null);
}
}
class X {
public void test(){
System.out.println("method call");
}
}
Output:
method call
More information in the docs.
Invokes the underlying method represented by this Method object, on the specified object with the specified parameters.
You have never specified an object nor parameters. My sample uses no parameters so I can put null instead. But either way you have to provide an instance as the first parameter (unless it is static).
I have a class with name "ConstituentSet". it has one method namely "getNucleusInConstSet()" which the output will be from "Proposition" class . The new Class "Proposition" have another method namely "getProperty()". I want to know what is the Propertry of my "Proposition Nucleus" in class "ConstituentSet". but i do not know how can i do that.
I wrote as follow but It does not work. (ConstituentSet.getNucleusInConstSet()).getProperty())
public class ConstituentSet{
// Constructor
private Proposition nucleusInConstSet;
public Proposition getNucleusInConstSet() {
return nucleusInConstSet;
}
}
public class Proposition{
//Constructor
private Property property;
public Property getProperty() {
return this.type;
}
}
You have:
(ConstituentSet.getNucleusInConstSet()).getProperty()
But you need to call an instance of ConstituentSet
e.g.
ConstituentSet cs = new ConstituentSet();
cs.getNucleusInConstSet().getProperty();
Note that this idiom (chained method calls) can be a pain. If one of your methods returns null, it's difficult to understand which one it is (without using a debugger). Note also that invocations of the form a().b().c().d() are a subtle form of broken encapsulation (a reveals that it has a b, that reveals it has a c etc.)
if you type ((ConstituentSet.getNucleusInConstSet()).getProperty()) you are attempting to call a static method of ConstituentSet.
You need to instantiate it and then call on that object.
ConstituentSet anInstanceOf = new ConstituentSet();
anInstanceOf.getNucleusInConstSet()).getProperty());
This won't work:
ConstituentSet.getNucleusInConstSet().getProperty();
Because the getNucleusInConstSet() method is not static. You have to use an instance of ConstituentSet, something like this:
ConstituentSet cs = new ConstituentSet();
cs.getNucleusInConstSet().getProperty();
Of course, you have to make sure that nucleusInConstSet is not null, or you'll get a NullPointerException. Initialize its value in ConstituentSet's constructor or set it using setNucleusInConstSet().
Alternatively, you could make getNucleusInConstSet() static, but I don't think that's the right thing to do in this case (but we don't have enough information about the problem to say so).
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();
well I'm wondering if it's possible to have a method where another method is passed as a parameter, so the first method can call the method passed in param?
Like for instance:
public void goToVisitManagementForm() throws ParseException {
if (isAuthenticated() && userTypeIs("Patient")) {
// I could have this whole block just moved to another method?
Panel newPanel = new Panel("Choose the details for your visit");
Component visitManagementForm = new VisitManagementForm(userData,
this);
newPanel.addComponent(visitManagementForm);
mainWindow.setMainPanel(newPanel);
} else {
authenticate();
}
}
If the code block would be moved to another method and it would be passed as a parameter to this method. How can I achieve that and is this a good practice? Because in this case I have the ifs that I always need to paste in...
What about other aspects of this?
This is called a higher-order function and you cannot do this in Java 7 or below. You can simulate passing functions to other functions through the use of an anonymous class that instantiates some interface the function expects, and then calling the function on that object.
For example, to pass a no-arg function:
interface Function {
void apply();
}
void takesAFunction(Function function) {
function.apply();
}
Then the following code snippet would do what you want:
Function myFunction = new Function() {
#Override
public void apply() {
// your code here.
}
};
takesAFunction(myFunction);
As a side note, reflection is extreme overkill for this type of problem.
You can pass methods as parameters using Java Reflection API.
First, you get a method object from a class:
Class c = MyClass.class;
Method[] methods = c.getMethods();
Method m = // choose the method you want
Then your function can take a Method object as a parameter:
public void aFunction(MyClass o, Method m);
And then inside that function you can invoke the method:
m.invoke(o);
This is a very simple example, where the method doesn't take any parameters. It's pretty easy to expand on this example and add the parameters as well.
Yes, but it is a very advanced procedure. You need to use the Method object. Here is the javadoc on Method:
here is the javadoc:
- http://docs.oracle.com/javase/6/docs/api/java/lang/reflect/Method.html
If I am understanding your question correctly, you want to be able to pass a method as a parameter. There really is no 'smooth' way to do this in Java. In objective C, it is built right into the language, (#selector tag)
I'm trying to solve the following issue in reflection. I've a POJO which kind of acts as a metadata for the method signature in TestResponse class. TestResponse has a setDate() methid which takes a Date parameter. I'm trying to make this is a generic code which can accept any method and its signature to set in the response. What I'm not able to figure out is how to set the parameter Class while calling getMethod() based on the input. The input tells me to set the parameter as Date, but not sure how to achiever that.
Here's my sample code. Ofcourse, the mdi.modifier.getClass() is wrong since it'll get String.class instead of Date.class.
TestResponse response = new TestResponse();
Object val = "test";
MDIBase mdi = new MDIBase("setDate", "Date");
Method m = response.getClass().getMethod(mdi.method, mdi.modifier.getClass());
m.invoke(response, new Object[] { val });
Here's MDIBase
public class MDIBase {
public String method;
public String modifier;
public MDIBase(String method, String modifier){
this.method = method;
this.modifier = modifier;
}
Any pointers will be highly appreciated.
Thanks
I'm not sure I fully understand you, but if I do, you want to be able to pass in a class name for the parameter?
In order to do that, instead of passing in "Date" pass in "java.util.Date" (this is known as the fully qualified class name) and then instead of getClass call
response.getClass().getMethod(mdi.method, Class.forName(mdi.modifier));
That will dynamically load the class that has the fully qualified name you supplied.
Is that what you're looking for? If not, give me some more information and I'll take another stab at it.