File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

[newbie] invoking methods within a class (java.lang.reflect)

 
Jon Camilleri
Ranch Hand
Posts: 664
Chrome Eclipse IDE
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'm trying to run a method within a class. The problem is that my logic never seems to get past the if statement. see code below.



 
Rob Spoor
Sheriff
Pie
Posts: 20372
44
Chrome Eclipse IDE Java Windows
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Method's toString() method doesn't return the name - it returns much more, including the modifiers, return type and parameters. Check out the getName() method instead.
 
Steve Luke
Bartender
Pie
Posts: 4181
21
IntelliJ IDE Java Python
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You are calling toString on the _methods object which is an array. You probably want to call it on the _m object which is a Method.

Or you could try to do a lookup for the method you want. I am sure this tutorial will show you how.
 
Jon Camilleri
Ranch Hand
Posts: 664
Chrome Eclipse IDE
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Steve Luke wrote:You are calling toString on the _methods object which is an array. You probably want to call it on the _m object which is a Method.

Or you could try to do a lookup for the method you want. I am sure this tutorial will show you how.


:) I realized I had that bug, but still haven't found a method for retrieving the methods for the "class" or the "instance of the class" that I want. Anyway thanks, I'll dig more...
:confused:

I'm actually reading the tutorial tutorial:



...and this is my code...



I'm passing






Output:
DEBUG runMethod: forName
DEBUG runMethod: forName
DEBUG runMethod: isAssignableFrom
DEBUG runMethod: isInstance
DEBUG runMethod: getModifiers
DEBUG runMethod: isInterface
DEBUG runMethod: isArray
DEBUG runMethod: isPrimitive
DEBUG runMethod: getSuperclass
DEBUG runMethod: getComponentType
DEBUG runMethod: toString
DEBUG runMethod: getName
DEBUG runMethod: asSubclass
DEBUG runMethod: cast
DEBUG runMethod: desiredAssertionStatus
DEBUG runMethod: getAnnotation
 
Campbell Ritchie
Sheriff
Pie
Posts: 47232
52
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Too difficult a question for us beginners. Moving.
 
Steve Luke
Bartender
Pie
Posts: 4181
21
IntelliJ IDE Java Python
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jon Camilleri wrote:
Steve Luke wrote:You are calling toString on the _methods object which is an array. You probably want to call it on the _m object which is a Method.

Or you could try to do a lookup for the method you want. I am sure this tutorial will show you how.


:) I realized I had that bug, but still haven't found a method for retrieving the methods for the "class" or the "instance of the class" that I want. Anyway thanks, I'll dig more...
:confused:


How about the getMethod(String methodName, Class<?>... argType) lookup?


I'm actually reading the tutorial tutorial:



...and this is my code...




There is something wrong with your brackets there. I see it as:

I am pretty sure that would give an else without an if compile error.


I'm passing



Employee.class.getClass().getClass() ? What Class file do you think you will be passing to the method?

Employee.class is an Object of type Class<Employee> (It is a Class Object which has the information for type Employee). So what happens when you call getClass() on an Object of type Class<Employee>? You get an Object of type Class<Class>. You then call getClass() again, which just gets you another reference to a Class<Class>. The end result is the Class Object you are passing into your method has nothing to do with Employee. It only holds information about the Class type (Class.class).

You then repeat the getClass().getClass() calls inside the method. I think you are a bit 'getClass()' happy. Stop calling that method :-)





Those two arguments mean different things. The first one is the Object whose instance method you want to call, while the second one is an argument that needs to be passed to the method in order to run. Have a look at this code:

If I wanted to call the setName(String) method on emp1 (using reflection) then I would need two Objects:
Object 1: emp1 - The Employee Object whose setName(String) method is to be executed
Object 2: n - The String Object which represents the name I am giving the employee.

So I would call your runMethod(...) like:

You had asked about using static methods in one of your comments. If you are calling a static method, then you do not need an Object to call the method on, which means you can pass in null for the third parameter. Also, if your method does not take any arguments than you can pass in null for the forth parameter. So in the above example, I could call the getCompany() static method like:


Note that the argument list for Method#invoke() is invoke(Object obj, Object... args). The invoke method takes an Object as the instance to call on, and a varargs argument (essentially an array) of Objects for arguments to the method (since a Method may have multiple arguments).


Output:
DEBUG runMethod: forName
DEBUG runMethod: forName
DEBUG runMethod: isAssignableFrom
DEBUG runMethod: isInstance
DEBUG runMethod: getModifiers
DEBUG runMethod: isInterface
DEBUG runMethod: isArray
DEBUG runMethod: isPrimitive
DEBUG runMethod: getSuperclass
DEBUG runMethod: getComponentType
DEBUG runMethod: toString
DEBUG runMethod: getName
DEBUG runMethod: asSubclass
DEBUG runMethod: cast
DEBUG runMethod: desiredAssertionStatus
DEBUG runMethod: getAnnotation
 
Jon Camilleri
Ranch Hand
Posts: 664
Chrome Eclipse IDE
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well, I've been through your comments, thank you very much, so I've chopped down the code a bit.
It seems like the actual class methods I am calling are not read.

:confused:



Output (nothing interesting here):
[Rob] removed over 2500 DEBUG lines [/Rob]
 
Rob Spoor
Sheriff
Pie
Posts: 20372
44
Chrome Eclipse IDE Java Windows
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You're still doing it on line 28: Class _cl = cl.getClass();
Just use cl all over the place, because that's the Class<Employee> object.

Also, next time filter out some of those debug print lines. There are over 2500(!) of those! And you don't even think they're important:
Output (nothing interesting here):

Suffice to say, I removed them. It's not really helpful indeed - they're just the methods from the Class class and its parent (Object).
 
Jon Camilleri
Ranch Hand
Posts: 664
Chrome Eclipse IDE
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Rob Prime wrote:You're still doing it on line 28: Class _cl = cl.getClass();
Just use cl all over the place, because that's the Class<Employee> object.

Also, next time filter out some of those debug print lines. There are over 2500(!) of those! And you don't even think they're important:
Output (nothing interesting here):

Suffice to say, I removed them. It's not really helpful indeed - they're just the methods from the Class class and its parent (Object).


Oh sorry, I thought they might indicate something to you, and, thanks again for correcting my typos. The code is going through a sample class, now I have to figure out how to return a value, preferably in a way that I can cast it from a generic type to the type returned by the method:

double salaryOfHarry = (double) HelperClassesforClasses.runMethod(_cl, "Salary", harry, null)

Is this possible?

Related links: http://java.sun.com/docs/books/tutorial/reflect/member/fieldValues.html

 
Rob Spoor
Sheriff
Pie
Posts: 20372
44
Chrome Eclipse IDE Java Windows
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jon Camilleri wrote:The code is going through a sample class, now I have to figure out how to return a value, preferably in a way that I can cast it from a generic type to the type returned by the method:

double salaryOfHarry = (double) HelperClassesforClasses.runMethod(_cl, "Salary", harry, null)

Is this possible?

If method Salary returns a double or Double, then yes. Although a) your runMethod needs to return Object (the result from _m.invoke, or something else if there is an exception or no method matches), b) you will need Java 5.0 or up for auto unboxing, and c) your method will not call _m.invoke because args == null.

Although that would still leave the risk of a NullPointerException if your runMethod returns null. It's better to use instanceof:
 
Jon Camilleri
Ranch Hand
Posts: 664
Chrome Eclipse IDE
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Rob Prime wrote:
Jon Camilleri wrote:The code is going through a sample class, now I have to figure out how to return a value, preferably in a way that I can cast it from a generic type to the type returned by the method:

double salaryOfHarry = (double) HelperClassesforClasses.runMethod(_cl, "Salary", harry, null)

Is this possible?

If method Salary returns a double or Double, then yes. Although a) your runMethod needs to return Object (the result from _m.invoke, or something else if there is an exception or no method matches), b) you will need Java 5.0 or up for auto unboxing, and c) your method will not call _m.invoke because args == null.

Although that would still leave the risk of a NullPointerException if your runMethod returns null. It's better to use instanceof:


Thanks (it's working)

NOTE: It would be helpful if this forum had an option to flag threads with status flags, because when searching for similar posts, I would probably give more importance to 'SOLVED' threads. This flag would be shown in the subject.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic