How to pass and invoke method references in Java - java

Let's say I have a class called Server, and I would like to allow others to write Plugins for it. Say Plugin is an Interface that extends Runnable and adds a single method: void init(...). It is the job of a plugin to collect data and send it to the server. When the time comes to send data to the server, however, how does it do this? Coming from C and C++ I am looking for a thinking along the lines of a function pointer. It seems to be possible in Java though I have not found examples outside the Java Standard Class Library.
How do I pass a method reference to the init method such that it can be stored by the Plugin, and then how do I invoke the method whenever the Plugin wants to send data? For now say that the desired Server method is: void sendData(Integer data).
For example:
// Inside Server
Plugin p = new PluginImplementation();
p.init(this::sendData);
// Plugin init
public void init(?? sendMethod) {
storedSendMethod = sendMethod;
// ...
}
// Plugin run
public void run() {
// ...
storedSendMethod(x) // Sends data to server
// ...
}

Using java.util.function.Function we can pass a function as an argument to a method, and then use apply() to apply it to the relevant arguments. Here's an example:
import java.util.function.Function;
public class FunctionDemo {
// we will pass a reference to this method
public static Integer square(Integer x) {
return x * x;
}
// this method accepts the function as an argument and applies it to the input: 5
public static Integer doSomething(Function<Integer, Integer> func) {
return func.apply(5);
}
public static void main(String[] args) {
// and here's how to use it
System.out.println(doSomething(FunctionDemo::square)); // prints 25
}
}
Additional version with multiple parameters (passed as an array):
public static Integer sum(Integer[] x) {
Integer result = 0;
for(int i = 0; i < x.length; i++)
result += x[i];
return result;
}
public static void main(String[] args) {
Integer[] arr = {1,2,3,4,5};
System.out.println(doSomething(Play::sum, arr));
}
public static Integer doSomething(Function<Integer[], Integer> func,
Integer[] arr) {
return func.apply(arr);
}

If the method is void sendData(Integer data) that corresponds to a consumer that takes an Integer and returns a void which is covered by the built in Consumer<Integer> interface which has an accept(Integer) method that will invoke your function when called.
So your code will look like this:
public void init(Consumer<Integer> sendMethod) {
storedSendMethod = sendMethod;
// ...
}
// Plugin run
void run() {
// ...
storedSendMethod.accept(x) // Sends data to server
// ...
}
As a sidenote, having an init method is probably a bad Java design. you are better moving the initialization to the constructor if possbile
Plugin p = new PluginImplementation( this::sendData);

In java, you do it with a callback,
This is your callback interface,
public interface SendCallback {
public void doSend(Object toSend);
}
This is the plugin interface, All plugin must implement this interface
public interface Plugin extends Runnable {
public void init(SendCallback callback);
}
This is the Server's code.
public class Server {
Plugin plugin;
SendCallback callback = new SendCallback() {
public void doSend(Object toSend) {
// logic to send object 'toSend'
}
}
public Server() {
plugin = new MyPlugin();
plugin.init(callback);
}
}
This is your plugin implementation.
public class MyPlugin implements Plugin {
SendCallback callback = null;
Object x = null;
public void init(SendCallback callback) {
this.callback = callback;
}
public void run() {
x = "Somthing"; // initialize the x object
callback.doSend(x);
}
}
You will notice, the server define the callback implementation.
The plugin will invoke the callback's method doSend.
I hope, this helps

There is method reference in Java 8, however you can just pass a whole object and call its sendData() method. In a 'plug-in' situation, using interfaces for each helps the plugin and the server have 'looser' coupling.
public interface Server {
void setData(...);
}
public class MyPlugin implements plugin {
private Server server;
void init(Server s ) {
this.server = s;
}
void run() {
...
this.server.setData(...);
...
}
}

interface Server{
...
void sendData(String message);
}
Plugin doesn't need a function reference, you can use the Server interface for informing Plugin to know about that method.
class PluginX implements Plugin{
...
private Server server;
void init(Server server) {
this.server = server;
}
public void run() {
// ...
server.sendData(x) // Sends data to server
// ...
}
}

Related

Ways to Avoid if-else, switch-case in Factory design pattern

I am designing a validation module. It has 100 error codes(i.e. errcd_01, errcd_02,..,errcd_100) to be validated. In input I am getting a specific error code(i.e. errcd_01) out of above 100.
Module should perform validation for that specific error code.
I am using factory pattern.
/* Interface */
public interface validateErrCd {
void check_errcd();
}
/* Concrete classes implementing the same interface */
public class validateErrCd_01 implements validateErrCd {
#Override
public void check_errcd() {
//business logic related to errcd_01
}
}
public class validateErrCd_02 implements validateErrCd {
#Override
public void check_errcd() {
//business logic related to errcd_02
}
}
.
.
.
public class validateErrCd_100 implements validateErrCd {
#Override
public void check_errcd() {
//business logic related to errcd_100
}
}
/* Factory */
public class ErrorValidationFactory {
//use check_errcd method to get object of type shape
public validateErrCd getValidation(String errorCode){
if(errorCode == null){
return null;
}
if(errorCode.equalsIgnoreCase("errcd_01")){
return new validateErrCd_01();
} else if(errorCode.equalsIgnoreCase("errcd_02")){
return new validateErrCd_02();
} ..
.......
else if(errorCode.equalsIgnoreCase("errcd_100")){
return new validateErrCd_100();
}
else {
return null;
}
}
}
/* I am using the Factory to get object of concrete class by passing an specific error code to be validated (i.e. "errcd_01"). */
public class FactoryPatternDemo {
public static void main(String[] args) {
ErrorValidationFactory errorFactory = new ErrorValidationFactory();
//get an object of validateErrCd_01 and call its check_errcd method.
validateErrCd errcd01 = errorFactory.getValidation("errcd_01");
//call check_errcd method of validateErrCd_01
errcd01.check_errcd();
}
}
Now due to multiple if/else inside Factory class ErrorValidationFactory, I am getting couple of CI/CD errors while performing mvn clean install.
e.g. [MethodLength] - checkstyle, Rule:CyclomaticComplexity - PMD.
So is there a way I can replace if/else, switch case kind of decision making inside factory which does not trigger above CI/CD errors in Java?
Note : If possible I would like to avoid reflection
You could use a Map:
public class ErrorValidationFactory {
private Map<String,Supplier<validateErrCd>> creators=new HashMap<>();
public ErrorValidationFactory(){
creators.put("errcd_100",validateErrCd_100::new);
//Same for others
}
//use check_errcd method to get object of type shape
public validateErrCd getValidation(String errorCode){
if(errorCode == null){
return null;
}
return creators.getOrDefault(errorCode,()->null);
}
}
Supplier is a functional interface that contains a method returning an object. SomeClass::new or ()->new SomeClass() means that the constructor of the class will be used for that.
This allows to to create the instances later.
If you want to create the Map only once, you can make it static and populate it in a static initializer.
However, if you really want to dynamically get the constructors, you would need to use reflection.

How to invoke a parameter to a void class?

I am dealing with the text extraction from pdf. To this end I wrote my own text extraction
strategy. I have one dynamic class and within this class i invoke text extraction strategy.
However, when i introduce some parameters to my dynamic class i cannot use them within strategy class. To be clear i am adding my code template below.
My question is briefly, is it possible to invoke parameter unq showing up in "get_intro" class, from renderText? Or other way around, can a variable or parameter created inside the "renderText" class be invoked in the "get_intro"?
public class trial {
public trial(){}
public Boolean get_intro(String pdf, String unq){
try { ....
for (int j = 1; j <= 3; j++) {
out.println(PdfTextExtractor.getTextFromPage(reader, j, semTextExtractionStrategy));
}
...} catch (Exception e) {
e.printStackTrace();
}
semTextExtractionStrategy part:
public class SemTextExtractionStrategy implements TextExtractionStrategy {
#Override
public void beginTextBlock() {
}
#Override
public void renderText(TextRenderInfo renderInfo) {
text = renderInfo.getText();...}
#Override
public void endTextBlock() {
}
#Override
public void renderImage(ImageRenderInfo renderInfo) {
}
#Override
public String getResultantText() {
//return text;
return main;
}
}
One could consider the following problematic solution:
public abstract class DefaultTextExtractionStrategy<D>
implements TextExtractionStrategy {
protected D documentInfo;
public final void setDocumentInfo(D documentInfo) {
this.documentInfo = documentInfo;
}
public class SemTextExtractionStrategy extends DefaultTextExtractionStrategy<SemDoc> {
#Override
public void beginTextBlock() {
documentInfo ...
}
public class SemDoc {
public String unq:
}
And in get_intro:
SemDoc semDoc = new SemDoc();
semDoc.unq = unq;
semTextExtractionStrategy.setDocumentInfo(semDoc);
out.println(PdfTextExtractor.getTextFromPage(reader, j, semTextExtractionStrategy));
The problem is that you want to pass some context class on calling the entry function (like ActionEvent or such). But by its name a strategy class probably is a stateless singleton. In the above solution you would need to instantiate from a Class<TextExctractionStrategy>, Class<D> a new strategy instance. Or like in the MouseAdapter class pass the same event class parameter to every method.
This smells of "over-designing" or a skewed pattern application.
As we are on the brink of Java 8 lambdas, you might even consider a "backport" of a design with lambdas.
But for the moment I would go with adding a generic D textExtractionContext to every called function, if the API is not for an external library.

RabbitMQ - Calling different implementations based on different conditions

I am trying to use RabbitMQ and based on different message, different implements should be called.
I set the message format as of JSON, and there is a field "callType", the value of it is the class name implements a common interface. e.g, all implementations have implements interface "Task", and I have implementation of "TaskImp1","TaskImp2","TaskImp3".
So the code should be like
if (callType=="TaskImp1")
((Task)TaskImp1).runTask()
if (callType=="TaskImp2")
((Task)TaskImp2).runTask()
if (callType=="TaskImp3")
((Task)TaskImp3).runTask()
But could it be more flexible? If later I develop a new one "TaskImp4", I don't want to change the calling code, is it possible to have java automatically pick the right implementation since the callType is actually the class name of the implementation.
Yes, for example, through Java reflection (What is reflection and why is it useful?). Reflection has a performance cost though (Java Reflection Performance)
Sure: put your Task instances in a map:
private Map<String, Task> tasksByName = new HashMap<>();
...
tasksByName.put("TaskImp1", new TaskImp1());
tasksByName.put("TaskImp2", new TaskImp2());
tasksByName.put("TaskImp3", new TaskImp3());
...
String callType = message.getCallType();
Task task = tasksByName.get(callType);
task.runTask();
Also, read How do I compare strings in Java?
You have an opportunity to use Strategy here. So for e.g. you could do like:
public class MyTask {
private Task task;
public MyTask(Task task) {
this.task = task;
}
public void doSomething() {
task.runTask();
}
public static void main(String args[]) {
MyTask task = new MyTask(new TaskImpl1());//or even you could use setTask() api to inject task at runtime rather than doing cast on compile time.
task.doSomething();
task = new MyTask(new TaskImpl2());
task.doSomething();
task = new MyTask(new TaskImpl3());
task.doSomething();
}
}
In this way you could make your code extensible. Tomorrow if you have taskImpl4, you could code it independently and inject in MyTask without even touching MyTask class implementation.
As #ovdsrn already said you can use reflection. Simple example would be something like (the key is getTask static method. Also, note that, when you are using Class.forName you must specify whole "path" (package) for your class)
// ITask.java
package main;
public interface ITask {
void doSomething();
}
// Task1.java
package main;
public class Task1 implements ITask {
#Override
public void doSomething() {
System.out.println("Task1");
}
}
// Task2.java
package main;
public class Task2 implements ITask {
#Override
public void doSomething() {
System.out.println("Task2");
}
}
// main
package main;
public class JavaTest {
private static ITask getTask(String name) {
try {
Class<?> cls = Class.forName(name);
Object clsInstance = (Object) cls.newInstance();
return (ITask)clsInstance;
} catch (Exception e) { // you can handle here only specific exceptions
return null;
}
}
public static void main(String[] args) {
String name = args.length > 0 ? args[0] : "Task2";
ITask task = getTask("main." + name);
if (task != null) {
task.doSomething();
}
else {
System.out.println("can not make instance of class: " + name);
}
}
}

C# equivalent of creating anonymous class that implements an interface

I've recently started using C#, and I wanted to find an equivalent method to this. I do not know what this is called, so I will simply show you by code.
With Java, I was able to create an interface like so:
public interface Event {
public void execute();
}
And pass this interface in a method's parameter like so:
public class TestEvent {
ArrayList<Event> eventList = new ArrayList<Event>();
public void addEvent(Event event){
eventList.add(event);
}
public void simulateEvent(){
addEvent(new Event() {
public void execute(){
//functionality
}
} );
}
public void processEvents(){
for(Event event : eventList)
eventList.execute();
}
}
EDIT : My question is revolved on the simulatEvent method from the TestEvent class, and if such an action is possible with C#.
I wanted to know if there was a way to do something similar to this with C#, (instantiating the interface in the simulateEvent method) and what this is actually called. Thank you!
Woof...ok, permit me to generalize a bit:
So in Java, you need a way to pass functions around. Java does not inherently support functions as first-class citizens, and this was one reason behind the implementation of anonymous classes - packaged groups of functions that can be declared inline and passed (as interfaces) to methods/other classes that will then call these functions.
In C#, functions are first-class citizens, and can be declared as either Delegates, Func<>s, or Action<>s. Let's try a comparison (of sorts):
Some sort of Java-y construct (my Java's fairly old, so bear with me):
public interface IDoSomething {
public int Return42();
public bool AmIPrettyOrNot(string name);
public void Foo();
}
public void Main(String[] args) {
DoStuff(new IDoSomething() {
public int Return42() { return 42; }
public bool AmIPrettyOrNot(string name) { return name == "jerkimball"; }
public bool Foo(int x) { ... }
});
}
public void DoStuff(IDoSomething something) { ... }
The (very rough) equivalent of this in C# would be:
public void Main(string[] args)
{
Func<int> returns42 = () => 42;
Func<string,bool> amIPretty = name => name == "jerkimball";
Action<int> foo = x => {};
}
Now, as others have mentioned, you usually see this pattern on the Java side when dealing with the handling of events - likewise on the C# side:
public class Foo
{
// define the shape of our event handler
public delegate void HandlerForBarEvent(object sender, EventArgs args);
// declare our event
public event HandlerForBarEvent BarEvent;
public void CallBar()
{
// omitted: check for null or set a default handler
BarEvent(this, new EventArgs());
}
}
public void Main(string[] args)
{
var foo = new Foo();
// declare the handler inline using lambda syntax
foo.BarEvent += (sender, args) =>
{
// do something with sender/args
}
foo.CallBar();
}
Note that we can also give it something with the same "shape":
public void MyHandler(object sender, EventArgs args)
{
// do stuff
}
public void Main(string[] args)
{
var foo = new Foo();
// that method above is the same "shape" as HandlerForBarEvent
foo.BarEvent += MyHandler;
foo.CallBar();
}
But it's also used in Java to define what Threads do, if memory serves (i.e., Runnable) - and we can do this as well in C#:
var thread = new Thread((Action)(() =>
{
// I'm the threads "run" method!
});
thread.Start();
Now, other stuff - enumeration:
public void processEvents(){
for(Event event : eventList)
eventList.execute();
}
C# has the same idea, just called differently:
public void processEvents()
{
// edit: derp, 'event' is a keyword, so I'm
// renaming this, since I won't get into why
// you could also use #event...
foreach(var evt in eventList)
{
evt.Execute();
}
}
EDIT: It looks like your question is about anonymous interface implementations instead of events. You can use the built-in Action delegate type instead of your Event interface.
You can then Action instances using lambda expressions. Your code would look like:
public class TestEvent
{
List<Action> eventList = new List<Action>();
public void addEvent(Action event){
eventList.add(event);
}
public void simulateEvent(){
addEvent(() => {
});
}
public void processEvents(){
for(Action event : eventList)
event();
}
}
You can use the delegate syntax instead of using () => { .. .} i.e.
delegate() { ... } in simulateEvent.
C# doesn't support anonymous interface implementations, so if your interface has multiple methods then you'll have to define a concrete class somewhere. Depending on the usage you could just have this class contain delegate properties which you can supply on creation e.g.
public class Delegates
{
public Action Event { get; set; }
public Func<string> GetValue { get; set; }
}
You can then create it like:
var anon = new Delegates
{
Event = () => { ... },
GetValue = () => "Value"
}

Callback functions in Java

Is there a way to pass a call back function in a Java method?
The behavior I'm trying to mimic is a .Net Delegate being passed to a function.
I've seen people suggesting creating a separate object but that seems overkill, however I am aware that sometimes overkill is the only way to do things.
If you mean somthing like .NET anonymous delegate, I think Java's anonymous class can be used as well.
public class Main {
public interface Visitor{
int doJob(int a, int b);
}
public static void main(String[] args) {
Visitor adder = new Visitor(){
public int doJob(int a, int b) {
return a + b;
}
};
Visitor multiplier = new Visitor(){
public int doJob(int a, int b) {
return a*b;
}
};
System.out.println(adder.doJob(10, 20));
System.out.println(multiplier.doJob(10, 20));
}
}
Since Java 8, there are lambda and method references:
Oracle Docs: Lambda Expressions
Oracle Docs: Method References
For example, if you want a functional interface A -> B, you can use:
import java.util.function.Function;
public MyClass {
public static String applyFunction(String name, Function<String,String> function){
return function.apply(name);
}
}
And here is how you can call it:
MyClass.applyFunction("42", str -> "the answer is: " + str);
// returns "the answer is: 42"
Also you can pass class method. For example:
#Value // lombok
public class PrefixAppender {
private String prefix;
public String addPrefix(String suffix){
return prefix +":"+suffix;
}
}
Then you can do:
PrefixAppender prefixAppender= new PrefixAppender("prefix");
MyClass.applyFunction("some text", prefixAppender::addPrefix);
// returns "prefix:some text"
Note:
Here I used the functional interface Function<A,B>, but there are many others in the package java.util.function. Most notable ones are
Supplier: void -> A
Consumer: A -> void
BiConsumer: (A,B) -> void
Function: A -> B
BiFunction: (A,B) -> C
and many others that specialize on some of the input/output type. Then, if it doesn't provide the one you need, you can create your own FunctionalInterface:
#FunctionalInterface
interface Function3<In1, In2, In3, Out> { // (In1,In2,In3) -> Out
public Out apply(In1 in1, In2 in2, In3 in3);
}
Example of use:
String computeAnswer(Function3<String, Integer, Integer, String> f){
return f.apply("6x9=", 6, 9);
}
computeAnswer((question, a, b) -> question + "42");
// "6*9=42"
And you can also do that with thrown exception:
#FunctionalInterface
interface FallibleFunction<In, Out, Ex extends Exception> {
Out get(In input) throws Ex;
}
public <Ex extends IOException> String yo(FallibleFunction<Integer, String, Ex> f) throws Ex {
return f.get(42);
}
For simplicity, you can use a Runnable:
private void runCallback(Runnable callback)
{
// Run callback
callback.run();
}
Usage:
runCallback(new Runnable()
{
#Override
public void run()
{
// Running callback
}
});
or with Java8 lambdas
runCallback(() -> {
// Running callback
});
yet i see there is most preferred way which was what i was looking for.. it's basically derived from these answers but i had to manipulate it to more more redundant and efficient.. and i think everybody looking for what i come up with
To the point::
first make an Interface that simple
public interface myCallback {
void onSuccess();
void onError(String err);
}
now to make this callback run when ever you wish to do to handle the results - more likely after async call and you wanna run some stuff which depends on these reuslts
// import the Interface class here
public class App {
public static void main(String[] args) {
// call your method
doSomething("list your Params", new myCallback(){
#Override
public void onSuccess() {
// no errors
System.out.println("Done");
}
#Override
public void onError(String err) {
// error happen
System.out.println(err);
}
});
}
private void doSomething(String param, // some params..
myCallback callback) {
// now call onSuccess whenever you want if results are ready
if(results_success)
callback.onSuccess();
else
callback.onError(someError);
}
}
doSomething is the function that takes some time you wanna add a callback to it to notify you when the results came, add the call back interface as a parameter to this method
hope my point is clear, enjoy ;)
A little nitpicking:
I've seem people suggesting creating a
separate object but that seems
overkill
Passing a callback includes creating a separate object in pretty much any OO language, so it can hardly be considered overkill. What you probably mean is that in Java, it requires you to create a separate class, which is more verbose (and more resource-intensive) than in languages with explicit first-class functions or closures. However, anonymous classes at least reduce the verbosity and can be used inline.
This is very easy in Java 8 with lambdas.
public interface Callback {
void callback();
}
public class Main {
public static void main(String[] args) {
methodThatExpectsACallback(() -> System.out.println("I am the callback."));
}
private static void methodThatExpectsACallback(Callback callback){
System.out.println("I am the method.");
callback.callback();
}
}
I found the idea of implementing using the reflect library interesting and came up with this which I think works quite well. The only down side is losing the compile time check that you are passing valid parameters.
public class CallBack {
private String methodName;
private Object scope;
public CallBack(Object scope, String methodName) {
this.methodName = methodName;
this.scope = scope;
}
public Object invoke(Object... parameters) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
Method method = scope.getClass().getMethod(methodName, getParameterClasses(parameters));
return method.invoke(scope, parameters);
}
private Class[] getParameterClasses(Object... parameters) {
Class[] classes = new Class[parameters.length];
for (int i=0; i < classes.length; i++) {
classes[i] = parameters[i].getClass();
}
return classes;
}
}
You use it like this
public class CallBackTest {
#Test
public void testCallBack() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
TestClass testClass = new TestClass();
CallBack callBack = new CallBack(testClass, "hello");
callBack.invoke();
callBack.invoke("Fred");
}
public class TestClass {
public void hello() {
System.out.println("Hello World");
}
public void hello(String name) {
System.out.println("Hello " + name);
}
}
}
A method is not (yet) a first-class object in Java; you can't pass a function pointer as a callback. Instead, create an object (which usually implements an interface) that contains the method you need and pass that.
Proposals for closures in Java—which would provide the behavior you are looking for—have been made, but none will be included in the upcoming Java 7 release.
When I need this kind of functionality in Java, I usually use the Observer pattern. It does imply an extra object, but I think it's a clean way to go, and is a widely understood pattern, which helps with code readability.
Check the closures how they have been implemented in the lambdaj library. They actually have a behavior very similar to C# delegates:
http://code.google.com/p/lambdaj/wiki/Closures
You also can do theCallback using the Delegate pattern:
Callback.java
public interface Callback {
void onItemSelected(int position);
}
PagerActivity.java
public class PagerActivity implements Callback {
CustomPagerAdapter mPagerAdapter;
public PagerActivity() {
mPagerAdapter = new CustomPagerAdapter(this);
}
#Override
public void onItemSelected(int position) {
// Do something
System.out.println("Item " + postion + " selected")
}
}
CustomPagerAdapter.java
public class CustomPagerAdapter {
private static final int DEFAULT_POSITION = 1;
public CustomPagerAdapter(Callback callback) {
callback.onItemSelected(DEFAULT_POSITION);
}
}
I tried using java.lang.reflect to implement 'callback', here's a sample:
package StackOverflowQ443708_JavaCallBackTest;
import java.lang.reflect.*;
import java.util.concurrent.*;
class MyTimer
{
ExecutorService EXE =
//Executors.newCachedThreadPool ();
Executors.newSingleThreadExecutor ();
public static void PrintLine ()
{
System.out.println ("--------------------------------------------------------------------------------");
}
public void SetTimer (final int timeout, final Object obj, final String methodName, final Object... args)
{
SetTimer (timeout, obj, false, methodName, args);
}
public void SetTimer (final int timeout, final Object obj, final boolean isStatic, final String methodName, final Object... args)
{
Class<?>[] argTypes = null;
if (args != null)
{
argTypes = new Class<?> [args.length];
for (int i=0; i<args.length; i++)
{
argTypes[i] = args[i].getClass ();
}
}
SetTimer (timeout, obj, isStatic, methodName, argTypes, args);
}
public void SetTimer (final int timeout, final Object obj, final String methodName, final Class<?>[] argTypes, final Object... args)
{
SetTimer (timeout, obj, false, methodName, argTypes, args);
}
public void SetTimer (final int timeout, final Object obj, final boolean isStatic, final String methodName, final Class<?>[] argTypes, final Object... args)
{
EXE.execute (
new Runnable()
{
public void run ()
{
Class<?> c;
Method method;
try
{
if (isStatic) c = (Class<?>)obj;
else c = obj.getClass ();
System.out.println ("Wait for " + timeout + " seconds to invoke " + c.getSimpleName () + "::[" + methodName + "]");
TimeUnit.SECONDS.sleep (timeout);
System.out.println ();
System.out.println ("invoking " + c.getSimpleName () + "::[" + methodName + "]...");
PrintLine ();
method = c.getDeclaredMethod (methodName, argTypes);
method.invoke (obj, args);
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
PrintLine ();
}
}
}
);
}
public void ShutdownTimer ()
{
EXE.shutdown ();
}
}
public class CallBackTest
{
public void onUserTimeout ()
{
System.out.println ("onUserTimeout");
}
public void onTestEnd ()
{
System.out.println ("onTestEnd");
}
public void NullParameterTest (String sParam, int iParam)
{
System.out.println ("NullParameterTest: String parameter=" + sParam + ", int parameter=" + iParam);
}
public static void main (String[] args)
{
CallBackTest test = new CallBackTest ();
MyTimer timer = new MyTimer ();
timer.SetTimer ((int)(Math.random ()*10), test, "onUserTimeout");
timer.SetTimer ((int)(Math.random ()*10), test, "onTestEnd");
timer.SetTimer ((int)(Math.random ()*10), test, "A-Method-Which-Is-Not-Exists"); // java.lang.NoSuchMethodException
timer.SetTimer ((int)(Math.random ()*10), System.out, "println", "this is an argument of System.out.println() which is called by timer");
timer.SetTimer ((int)(Math.random ()*10), System.class, true, "currentTimeMillis");
timer.SetTimer ((int)(Math.random ()*10), System.class, true, "currentTimeMillis", "Should-Not-Pass-Arguments"); // java.lang.NoSuchMethodException
timer.SetTimer ((int)(Math.random ()*10), String.class, true, "format", "%d %X", 100, 200); // java.lang.NoSuchMethodException
timer.SetTimer ((int)(Math.random ()*10), String.class, true, "format", "%d %X", new Object[]{100, 200});
timer.SetTimer ((int)(Math.random ()*10), test, "NullParameterTest", new Class<?>[]{String.class, int.class}, null, 888);
timer.ShutdownTimer ();
}
}
I've recently started doing something like this:
public class Main {
#FunctionalInterface
public interface NotDotNetDelegate {
int doSomething(int a, int b);
}
public static void main(String[] args) {
// in java 8 (lambdas):
System.out.println(functionThatTakesDelegate((a, b) -> {return a*b;} , 10, 20));
}
public static int functionThatTakesDelegate(NotDotNetDelegate del, int a, int b) {
// ...
return del.doSomething(a, b);
}
}
it's a bit old, but nevertheless... I found the answer of Peter Wilkinson nice except for the fact that it does not work for primitive types like int/Integer.
The problem is the .getClass() for the parameters[i], which returns for instance java.lang.Integer, which on the other hand will not be correctly interpreted by getMethod(methodName,parameters[]) (Java's fault) ...
I combined it with the suggestion of Daniel Spiewak (in his answer to this); steps to success included: catching NoSuchMethodException -> getMethods() -> looking for the matching one by method.getName() -> and then explicitly looping through the list of parameters and applying Daniels solution, such identifying the type matches and the signature matches.
with java 8 this task is kinda easy, if you want to use callback in multi-thread scenario you can do something similar like the following:
public void methodA (int n, IntConsumer consumer) {
// create a thread
Thread t = new Thread(() -> {
// some time consuming operation
int result = IntStream.range(0, n).sum();
// after the result is ready do something with it.
consumer.accept(result);
});
t.start();
}
and to use this method do:
methodA(1000000, System.out::println);
public class HelloWorldAnonymousClasses {
//this is an interface with only one method
interface HelloWorld {
public void printSomething(String something);
}
//this is a simple function called from main()
public void sayHello() {
//this is an object with interface reference followed by the definition of the interface itself
new HelloWorld() {
public void printSomething(String something) {
System.out.println("Hello " + something);
}
}.printSomething("Abhi");
//imagine this as an object which is calling the function'printSomething()"
}
public static void main(String... args) {
HelloWorldAnonymousClasses myApp =
new HelloWorldAnonymousClasses();
myApp.sayHello();
}
}
//Output is "Hello Abhi"
Basically if you want to make the object of an interface it is
not possible, because interface cannot have objects.
The option is to let some class implement the interface and then call that function using the object of that class.
But this approach is really verbose.
Alternatively, write new HelloWorld() (*oberserve this is an interface not a class) and then follow it up with the defination of the interface methods itself. (*This defination is in reality the anonymous class).
Then you get the object reference through which you can call the method itself.
Create an Interface, and Create the Same Interface Property in Callback Class.
interface dataFetchDelegate {
void didFetchdata(String data);
}
//callback class
public class BackendManager{
public dataFetchDelegate Delegate;
public void getData() {
//Do something, Http calls/ Any other work
Delegate.didFetchdata("this is callbackdata");
}
}
Now in the class where you want to get called back implement the above Created Interface.
and Also Pass "this" Object/Reference of your class to be called back.
public class Main implements dataFetchDelegate
{
public static void main( String[] args )
{
new Main().getDatafromBackend();
}
public void getDatafromBackend() {
BackendManager inc = new BackendManager();
//Pass this object as reference.in this Scenario this is Main Object
inc.Delegate = this;
//make call
inc.getData();
}
//This method is called after task/Code Completion
public void didFetchdata(String callbackData) {
// TODO Auto-generated method stub
System.out.println(callbackData);
}
}
Simpliest and easiest way is by creating a reusable model and trigger.... https://onecompiler.com/java/3wejrcby2?fbclid=IwAR0dHbGDChRUJoCZ3CIDW-JQu7Dz3iYGNGYjxYVCPCWfEqQDogFGTwuOuO8

Categories