Methods passed through parameters , reflection

So most people know that in languages such as python and c++ you can pass a function as a parameter, obviously it is much simpler when its done in python. Java falls in the middle its not a pointer but its not just a variable instead you must define an object.
This tutorial is going to teach you guys the wonderful world of Methods as parameters , this is useful when building handling classes and especially for tick functions when you just want to bind the methods.

Lets have a look at the basic structure of the program we are going to create and the objects we will need.

Obtain method object
figure out how we bind and create the callable object
call object

Those are the first things that we will cover.
To obtain the method object what do we do?
Here is some example code:


Method value = instance.getMethod(name, null);

The first bit is obvious we are declaring and instantiating an object what about the other two bits , well .getMethod return a Method object , its parameters are the name of the function in a string and a Classlist of its parameters.
instance , this is the object of which the function is inside instance is defined as this.getClass() where this is the class where the function is defined. So lets put this inside of a method.


public Method obtain_method(Class instance,String name){
		try {
			Method value = instance.getMethod(name, null);

			return value;
		} catch (NoSuchMethodException | SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
		return null;
	}

and how do we call this?


Method a = obtain_method(this.getClass(), "close");
public void close(){
    System.out.println("hi");
}

Well goody , we have a method but what do we do with it? well this is no longer a function its an object , we can pass it through parameters and access its members. To pass it it is as simple as (Method method).
But we dont want to just do that , we want to be able to call this .
Its simple to call this


value.invoke(instance);

So this is very similar to the definition method however this is not the same instance parameter , this is the Object form not the class for so instance isnt this.getClass() it is just this.
If the function has an return types how do we recieve them , well its just as simple as performing this.
Object a = value.invoke(instance);
when invoke is called , its return type is an object, if the type is void then null is returned , if the return type is anything else Object is returned. This isnt very useful so we must know what type it is, we can do this simply by doing this.


Type a = (Type)value.invoke(instance);

So we know how to create a Method object and invoke the function but its not very useful as we still have to keep tabs on all the other Types and parameters , to get around this we will create an object, the way I came up with was called an Encapsulated_method, this stores the parameters from the object .


package com.lcass.util;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Encapsulated_method {
	public Method method;
	public Object instance;
	public Object[] parameters;

	public Encapsulated_method(Method method, Object[] parameters,
			Object instance) {
		this.method = method;
		this.parameters = parameters;
		this.instance = instance;
	}

	public void call() {
		if(instance == null){
			return;
		}
		if(method == null){
			return;
		}
		if (parameters != null) {
			try {
				method.invoke(instance, parameters);
			} catch (IllegalAccessException | IllegalArgumentException
					| InvocationTargetException e) {
				e.printStackTrace();
			}
		} else {
			try {
				method.invoke(instance);
			}
			catch (IllegalAccessException | IllegalArgumentException
					| InvocationTargetException e) {
				e.printStackTrace();
			}
		}
	}
	public Object call_back(){
		Object temp;
		if(instance == null){
			System.out.println("no instance");
			return null;
		}
		if(method == null){
			System.out.println("no method");
			return null;
		}
		if (parameters != null) {
			try {
				temp = method.invoke(instance, parameters);
				return temp;
			} catch (IllegalAccessException | IllegalArgumentException
					| InvocationTargetException e) {
				e.printStackTrace();
			}
		} else {
			try {
				temp = method.invoke(instance);
				return temp;
			}
			catch (IllegalAccessException | IllegalArgumentException
					| InvocationTargetException e) {
				e.printStackTrace();
			}
		}
		return null;
	}
}

lets run through this.
Firstly three variables are defined , the Method object itself , the instance Object and an array of Object[] parameters, these are fairly simple.
The constructor simple binds three parameters to these variables.
Call(){
}
this firstly checks to see if the values exist in order to stop errors.
the final check sees if you have inputted any parameters, if our function has no parameters then attempting to call it will result in an error.
When call method.invoke three errors can be thrown by the JRE , Illegal access , Arguement and InvocationTarget , ensure that these are included within the catch as I have done. method.invoke(instance,parameters); is the next function , it calls the function , however you will notice that it does not have a return type this is because this is handled later.
After that the else look clause is called with method.invoke(instance); where no parameters are passed.

Callback acts in almost the same way as call() however it returns an Object,
The only bit that changed is temp = method.invoke(instance,parameters) ;return temp;

There it is , our handling of methods , I hope this was helpful to you guys.

The only time I’d use reflection would be for invoking unknown method signatures. Pre java 8 - method objects and java 8+ method handles.