Ill try to make it short.
I want to iterate through the methods of a class via "getMethods()". Now when the method has a Parameter which is an instance of the "Event" class, it should be invoked.
Example Method:
private void onEvent(ExampleEvent event) {...]
"ExampleEvent" is an instance of the "Event" class.
Help is appreciated!
You want to use getParameterTypes() instead of getParameters(). If you want to match a parameter type to a parameter name, simply index the two arrays the same.
Something Like this, its been awhile since i wrote in java but This something like this should work
Method[] methods = Class.getMethods();
List<Method> methodsWithEvent = new List<Method>();
for(Method method : methods){
Class[] params = method.getParameterTypes();
for(Class class : params)
if(typeof(class) == typeof(ExampleEvent))
methodsWithEvents.add(method);
}
Related
I am trying to call getter method on object but which getter to call depends on the value in a variable.
public void met1(String var) {
MyClass m = new MyClass();
if(var.equals("A"))
m.getA();
if(var.equals("B"))
m.getB();
if(var.equals("C"))
m.getC();
}
This is one way. Another could be using switch but I don't want to hardcode values as they may change. Is there any better way of doing this?
String is a class not a primitive type, you can't compare instances of String class like var using == this will not work!!!
You need to use method equals like: if(var.equals("A")) then ... .
Apart form that this way is fine.
Another way would be using reflection without if-statement:
Class<?> c = Class.forName("MyClass");
Object my_object = c.newInstance();
Method setNameMethod = my_object.getClass().getMethod("get"+var,String.class);
setNameMethod.invoke(my_object, var);
What is this type of passing constructor to a method called in Java
(the Class_name is an internal class)?
method_name(new Class_name(arguments));
How can we pass constructor without having an instance of the object?
Well, actually new Class_name(arguments) will create a new instance of the class. A construction might be useful - it is more concise than
Class_name instance = new Class_name(arguments);
method_name(instance);
but you would not be able to access instance later on.
As has been said, you are passing a new object.
If you want to pass just the information about this class, then your method would need to take a Class an an argument, for example...
public void method_name(Class clz) { ... do something... )
You would call it like this...
method_name( Class_name.class);
The other thing doing literally what you wanted would be to give the Constructor, which you can get, for example, by...
Constructor const = Class_name.class.getConstructor( ArgumentType.class, AnotherArgumentType.class, ...);
for example...
Constructor const = Class_name.class.getConstructor( String.class);
...if your constructor took one String argument.
And then call your method...
public void method_name(Constructor constructor) { ... do something... )
... with...
method_name( const );
The last way is very specific and I doubt that it's actually what you NEED, no matter what you think you might need.
new creates a object and this is passed to the function. You are not passing class you are passing "new" of that class which will create a object
You are not passing a constructor, an instance :
When you do :
MyClass myClass = new Myclass();
method_name(myClass);
You have an instance of MyClass into myClass. then you call method_name with myClass as an argument
So this can be shortened as :
method_name(new Myclass());
These types of use cases are very common for Decorator design pattern, where you do not require the intermediate objects.
Example:
FileReader fr = new FileReader(filename);
LineNumberReader lnr = new LineNumberReader(fr);
or
LineNumberReader lnr = new LineNumberReader(new FileReader(filename));
Take a look at I/O classes from nio framework for more understanding on these types of use cases.
In Java, or Groovy, say I have a String array like
myArray = ["SA1", "SA2", "SA3", "SA4"]
I want to call a different function based off of each string.
class Myclass{
public static void SA1() {
//doMyStuff
}
public static void SA2() {
//doMyStuff
}
...etc
}
I would love to be able to loop through my array and call the functions that they pertain to without having to compare the string or make a case statement. For example is there a way to do something like the following, I know it doesn't currently work:
Myclass[myArray[0]]();
Or if you have suggestions of another way I can structure something similar.
In groovy you can do:
Myclass.(myArray[0])()
In Java you can do:
MyClass.class.getMethod(myArray[0]).invoke(null);
In Groovy, you can use a GString for dynamic method invocation:
myArray.each {
println Myclass."$it"()
}
You can, for instance, declare an interface such as:
public interface Processor
{
void process(String arg);
}
then implement this interface, for example in singletons.
Then create a Map<String, Processor> where keys are your strings, values are implementations and, when invoking:
Processor p = theMap.containsKey(theString)
? theMap.get(theString)
: defaultProcessor;
p.process(theString);
I suggest you look at Reflection APIs, to call methods at runtime
check Reflection docs
Class cl = Class.forName("/* your class */");
Object obj = cl.newInstance();
//call each method from the loop
Method method = cl.getDeclaredMethod("/* methodName */", params);
method.invoke(obj, null);
I have this code:
public static final <TypeVO extends BaseVo> List<SelectItem> populateSelectBoxForType(
final Class<TypeVO> voClass, final String fieldName) {
List<SelectItem> listSelectBox = null;
final List<TypeVO> vosList = GenericEjbProxyFactory
.getGenericTopValueObjectProxy(voClass)
.getAllValueObjects(null);
System.out.println("loaded vosList!!!!");
if (vosList != null) {
listSelectBox = new ArrayList<SelectItem>();
for (final TypeVO currVo : vosList) {
listSelectBox.add(new SelectItem(currVo.getInternalId(), currVo.getName()));
}
}
return listSelectBox;
}
As you see here, I'm using currVo.getName because always, currVo has a name property.
I want to be able to use also other fields from this currVo which has type as voClass, but not all currVo classes will contain this field so I have to use reflection to identify these getField method, something like:
for (final TypeVO currVo : vosList) {
for (final Method m : voClass.getMethods()) {
if (m.getName().contains(fieldName)) {
listSelectBox.add(new SelectItem(
currVo.getInternalId(), currVo.m));
}
}
}
What I do not know is HOW I can use that specific method's value when I find it, exactly like currVo.getName (because, of course, currVo.m is wrong)?
Eg: If fieldName is "Age" I want to put in the list: currVo.getAge()... I am simply blocked here...
m.invoke(currVo);
See also:
Method javadoc
Also note the correct way to look for a method as suggested by Nik and Bohemian.
Do I understand it correctly that you want to invoke the method m on your object currVo? Then it's simply
m.invoke(currVo);
Use reflection to get the getFieldName method and invoke it, as follows:
Method method = voClass.getMethod("get" + fieldName); // the getter with no params in the signature
Object value = method.invoke(currVo}); // invoke with no params
listSelectBox.add(new SelectItem(currVo.getInternalId(), value));
Note: This assumes that fieldName is leading uppercase, eg "Value", not "value", so prepending it with "get" gives the exact method name, eg "getValue"
You should use the invoke method from the Method class.
m.invoke(currVo, (Object[]) null);
(Assuming the method takes no parameter.)
This will work for JDK versions 1.4 and later, since they state:
If the number of formal parameters required by the underlying method is 0, the supplied args array may be of length 0 or null
The one-parameter version of that call will not work on older JVMs.
I am not sure if i got ur question right, but what i feel u are asking wud be answered by following code:
// Class is whatever is the type u r using
Method mthd = Class.getMethod("get" + fieldName); //in case method don't have any parameters.
listSelectBox.add(mthd.invoke(currVo));
otherwise ignore.
I'm trying to invoke a method that takes a super class as a parameter with subclasses in the instance.
public String methodtobeinvoked(Collection<String> collection);
Now if invoke via
List<String> list = new ArrayList();
String methodName = "methodtobeinvoked";
...
method = someObject.getMethod(methodName,new Object[]{list});
It will fail with a no such method Exception
SomeObject.methodtobeinvoked(java.util.ArrayList);
Even though a method that can take the parameter exists.
Any thoughts on the best way to get around this?
You need to specify parameter types in getMethod() invocation:
method = someObject.getMethod("methodtobeinvoked", Collection.class);
Object array is unnecessary; java 1.5 supports varargs.
Update (based on comments)
So you need to do something like:
Method[] methods = myObject.getClass().getMethods();
for (Method method : methods) {
if (!method.getName().equals("methodtobeinvoked")) continue;
Class[] methodParameters = method.getParameterTypes();
if (methodParameters.length!=1) continue; // ignore methods with wrong number of arguments
if (methodParameters[0].isAssignableFrom(myArgument.class)) {
method.invoke(myObject, myArgument);
}
}
The above only checks public methods with a single argument; update as needed.