Having the same method with two different behaviors? - java

My question is not Java specific but I think it's more like a design-patterns question.
I'll try to explain with an example :
I have two classes (A and B), B is extending A.
The two classes look like this :
public class A {
protected int method1() {
System.out.println(method3());
}
protected int method3() {
return 3;
}
}
.
public class B extends A {
protected void method2() {
//Calling method1
method1(); // Output : 3
//Calling method1 another time but method3 needs to be slightly different
method1(); // Output needs to be : 6
}
}
So, I'd like to call two times the same method but I want to modify what is inside method3() when calling it the second time.
Obviously I don't want to define two different method1() because method1 is not only printing out an int but it is doing more.
The second method3 could look like this :
protected int method3bis() {
return 2*3;
}
I'd really like to avoid passing some kind of argument through all the methods, something which would look like this :
protected int method1(int arg) {
if(arg == 0)
System.out.println(method3());
if(arg == 1)
System.out.println(method3bis());
}
Do you know any good way to do this ?
Thanks in advance :-)

There is no way to change the implementation of a method at run time in Java.
When you override a method, it is possible to call the direct superclass implementation, for example:
class Super {
void method1() {
System.out.println(3);
}
}
class Sub {
#Override
void method1() {
System.out.println(2 * 3);
}
void method2() {
// printing 3
super.method1();
// printing 6
this.method1();
}
}
However, this cannot be used in the way you have described (calling method1 while changing the implementation of method3). And it would also be a very disorganized way to implement what you have described.
You should use method parameters because this is what they are for.

You can accomplish this with reflection by creating a new A object, but this is not a good way to go about it. You're better off using if/else blocks.
import java.lang.reflect.*;
public class B extends A {
protected void method2() {
try {
Class a = Class.forName("A");
Object aa = a.newInstance();
((A) aa).method1(); // Output : 3
} catch (Exception e) {
e.printStackTrace();
}
//Calling method1 another time but method3 needs to be slightly different
this.method1(); // Output needs to be : 6
}
#Override
protected int method3() {
return 2*3;
}
}

Related

Is there a way to overload an abstract method in a functional interface?

I would like to be able to provide a functional interface that accepts several different types of lambda functions.
I read this. The first answer to this question clarifies why overloading an abstract method in a functional interface could cause undefined behavior. However, is there a way to do the equivalent of overloading an abstract method in a functional interface if I supply all of the defaults?
I would like to be able to write something like the following code:
Ball b = () -> System.out.println("You hit it!");
Ball ba = (boolean miss) -> System.out.println(miss);
b.hit();
b.hit(false);
ba.hit();
ba.hit(false);
The desired result would be:
You hit it!
default false
default hit
false
Consider the following (non-compilable) code (mostly copied from the linked question):
#FunctionalInterface
public interface Ball
{
void hit();
void hit(boolean miss);
default void hit(){
System.out.println("default hit");
}
default void hit(boolean miss){
System.out.println("default" + miss);
}
}
I am looking for an alternative to this code that would compile.
You could wrap the interface in a class and then pass on the method calls to the interfaces internally.
Example code:
public class Test{
public static void main(String... args) throws Exception{
Ball b = new Ball(() -> System.out.println("You hit it!"));
Ball ba = new Ball((boolean miss) -> System.out.println(miss));
b.hit();
b.hit(false);
ba.hit();
ba.hit(false);
}
public static class Ball{
final Hit a;
final HitBoolean b;
public Ball(Hit a){
this.a = a;
b = (miss) -> System.out.println("default " + miss);
}
public Ball(HitBoolean b){
this.b = b;
a = () -> System.out.println("default hit");
}
public void hit(){
a.hit();
}
public void hit(boolean miss){
b.hit(miss);
}
}
public interface Hit{
void hit();
}
public interface HitBoolean{
void hit(boolean miss);
}
}
Output of the program:
You hit it!
default false
default hit
false
You could do something like this. But you would need to name your variables properly to keep track of both the arg and the consumer that takes it.
#FunctionalInterface
interface Ball<T> {
void hit();
static <T> Ball<T> withArg(T arg, Consumer<T> com) {
return () -> com.accept(arg);
}
}
public class Demo {
public static void main(String[] args) {
Ball<Boolean> b = () -> System.out.println("You Hit it!");
b.hit();
Ball<Boolean> ba = Ball.withArg(false, a -> System.out.println(a));
Ball<Boolean> bb = Ball.withArg(true, a -> System.out.println(a));
ba.hit();
bb.hit();
}
}
first thing about functional interface is , it can have only one abstract method.In that case you cant even think of the second method (let it be abstract method too). you can have any number of default methods.
So answer is 100% not possible and Your code above will get compilation error as you kept #FunctionalInterface annotation which strictly prohibits keeping more than one abstract method.
As per your code
#FunctionalInterface
public interface MyInter {
public abstract void fly();
public abstract void fly(int a);
default void fly() {} \\line1
default void fly(int g) { } \\line2
}
line 1 and 2 will throw compile time error as java sees them by method name are same and argument types are same , they will never bother of return type or default or etc..(primary rule of overloading).
more over if remove line 1 and 2 , then too code will throw error because #functionalinterface will give compilation error stating invalid '#FunctionalInterface' annotation; MyInter is not a functional interface .
Hope this answers your question...

How can I split a methods functionality using an enum as condition?

I have the following code:
enum Example {
ex1,ex2
}
public void method(Example exType) {
if(exType.equals(ex1)) {
//do similar stuff
method2(exType)
} else if(exType.equals(ex2)) {
//do similar stuff
method2(exType)
} else {
//throw exception
}
}
public void method2(Example exType) {
if(exType.equal(ex1)) {
//do similar stuff
} else if(exType.equals(ex2)) {
//do similar stuff
} else {
//throw exception
}
}
The problem is the method calls other methods that behave in the same way. So it doesn't look very good as an implementation. How can i split this behavior?
Edit:
Using enum is not mandatory. Similar means they call same-named method and update same-named fields, one just does less than the other. Inside the //Do similar stuff it calls another method with the enum as a parameter and that method has the same structure of code.
Edit 2:
Added some more code. This just doesn't seem like the right approach
It's worth remembering that Enum values are objects rather than int values like they are in other languages. This allows you to use polymorphism with them removing the need for switch statements in many cases.
interface IExample {
// you can use interfaces if you need them
void method1();
}
enum Example implements IExample {
ex1 {
public void method1() {
// do stuff
method2();
}
public void method2() {
// do other stuff
}
},
ex2 {
public void method1() {
// do stuff
method2();
}
public void method2() {
// do other stuff
method3(); // not all methods need to be different.
}
};
public abstract void method1(); // only needed if you don't use an interface
public abstract void method2(); // does it need to be public as well?
public void method3() { /* added as an example */ }
}
There is no need to throw an exception as your code won't compile if you forget to provide an implementation for a new enum value.
The IExample might be an existing interface or it might be needed for extention. e.g.
class Example2 implements IExample {
int x;
public Example2(int x) { this.x = x; }
public void method1() {
// uses x
}
}
Now you can write
IExample e = Example.ex1; // fixed value
IExample e2 = new Example2(5); // extendable at runtime.
Why would you do this?
There is an example I use.
SystemTimeProvider - a singleton implemented as an enum
SetTimeProvider a class where each instance can have a different fixed time for testing purposes.
I would use a switch instead. Also with Enums you can use ==, but you don't need that when using a switch. What about this!
enum Example {
ex1,ex2
}
public void method(Example exType) {
switch (exType) {
case ex1:
// do 1
break;
case ex2:
// do 2
break;
default:
//throw exception
}
}
First of all its better to use switch case because in case in future there are more no of enums and then more no of if conditions then code becomes less readable.
One of the approach could be
enum Example {
ex1,ex2
}
public void method(Example exType) {
switch (exType) {
case ex1:
methodEx1();
break;
case ex2:
methodEx1();
break;
default:
//throw exception
}
}
Function methodEx1(); and methodEx2(); add all the codes corresponds to enum in a single function instead of writing of multiple function for same enum.

Refactoring - Methods share the same code except for one function call

I have several methods in class Test which have the same code except one specific method call. Is there a possibility to merge these methods together (bellow into function foo) and call foo and tell it which method to call without doing a bigger switch or if/else statement? An important note is that foo is only called from inside the class Test (therefore foo is private) and the function foo itself calls different methods from one class Bar. Class Bar and Test are not in the same inheritance tree.
class Test {
/* ... */
private void foo("Parameter that specifies which method to call from class Bar")
{
/* merged code which was equal */
Bar bar = new Bar();
bar.whichMethod(); // Call the method (from Class Bar) specified in the Parameter
/* merged code which was equal*/
}
/* ... */
}
Sure straight forward I'd add some kind of switch("which Method to call") statement. But is there a better way to do this?
You can pass the method to call as an argument. Let's assume that the method to call has the following signature:
private void m() {...}
You could write:
private void foo(Runnable methodToRun) {
//...
methodToRun.run();
//...
}
and your various foo methods would be like:
private void foo1() { foo(new Runnable() { public void run() { someMethod(); } }); }
With Java 8 you could also pass a lambda or a method reference.
As assylias said, you can use Method References with Java 8.
public void testAdds() {
doTest(this::addOne);
doTest(this::addTwo);
}
private void doTest(Function<Integer,Integer> func) {
System.out.println("Func(41) returns " + func.apply(41));
}
public int addOne(int num) {
return num + 1;
}
public int addTwo(int num) {
return num + 2;
}

Can I use an If statement to check which method made the call?

I want to make an if statement that checks to see which method made the call to a secondary method.
I will write what i want in pseudo code so you can see what I mean.
public static void methodOne() {
methodToCall();
}
public static void methodTwo() {
methodToCall();
}
public static void methodThree() {
methodToCall();
}
public static void methodToCall() {
if (methodOne made the call == true) {
execute this
} else if (methodTwo made the call == true){
execute this
} else if (methodThree made the call == true){
execute this
} else {
System.out.println("How did you get here?");
}
}
That's about the gist of it. I want a simple check to see which method made the call so I can choose which operation is relevant to the call.
Is this possible?
If it is not possible, is there a work around?
This is called 'state orientation', and it was debated extensively in the 1970s, possibly even the 1960s. The conclusion was that if you need to know this sort of thing you are already doing something seriously wrong, by introducing a two-way dependency into the code. What happens for example when you add another caller?
Use three short methods, instead of combining the logic of three short methods into one larger method. Once the short methods are created Just call the appropriate method from each calling method.
public static void methodOne() {
methodToCall1();
}
public static void methodTwo() {
methodToCall2();
}
public static void methodThree() {
methodToCall3();
}
public static void methodToCall1() {
int x = 0;
x = x - 3; //some custom logic to prep argument
commonLogic(x);
}
public static void methodToCall2() {
//Method 2 logic
int x = 0;
x = x + 3; //some custom logic to prep argument
commonLogic(x);
}
public static void methodToCall3() {
//Method 3 logic
int x = 0;
x = x * 3; //some custom logic to prep argument
commonLogic(x);
}
public static void commonLogic(int arg1){
//peform common logic
}
If these three methods would contain duplicate code, abstract the duplicate code into another method then call that method from within each of the smaller methods. The idea is to prepare the arguments to call the common function in each of the three smaller functions, then call the common function with those arguments.
A great deal of the abstraction afforded by methods comes from the fact that they do not need to know who is calling them, so the answer to your question is "no". It does not mean that you cannot make it work, though: make the callers pass some sort of a token (say, an enum value) identifying themselves to the callee. This would let you dispatch on that identity inside your method's implementation:
enum CallerContext {CALLER1, CALLER2, CALLER3};
...
public static void methodToCall(CallerContext context) {
...
}
This is not the most Object-Oriented way of doing things, however: very often, a better approach would be letting the callers supply the logic to be executed, rather than supplying a token identifies that logic. See Visitor Pattern for details on that approach.
You can do it by examining the call stack via Thread.getStackTrace():
public static void methodToCall(Action action) {
String callingMethod = Thread.currentThread().getStackTrace()[2].getMethodName();
if (callingMethod.equals("methodOne")) {
execute this0
} else if (callingMethod.equals("methodTwo")) {
execute this
} else if (callingMethod.equals("methodThree")) {
execute this
} else {
System.out.println("How did you get here?");
}
}
but you shouldn't - it's a bit anti-OO. Instead, change your method signature to something like this:
public enum Action {ONE, TWO, THREE}
public static void methodToCall(Action action) {
if (action == ONE) {
execute this
} else if (action == TWO) {
execute this
} else if (action == THREE) {
execute this
} else {
System.out.println("How did you get here?");
}
}
If you end up using an enum, then make sure to take advantage of the fact that enums in Java are no less than singleton instances of classes. Therefore you can declare the method as abstract in the enum definition and then override it in each instance, instead of passing the enum as a paramater to some method defined outside of the enum's context.
So it would look something like:
enum Method {
Mode1 {
#Override
void call() {
// do stuff
}
}, Mode2 {
#Override
void call() {
// do stuff differently
}
}, Mode3 {
#Override
void call() {
// do stuff even more differently
}
};
abstract void call();
}
And then you either don't need your wrapping methods, or, if they were supposed to do anything more, you write:
public static void methodOne() {
// some code
Method.Mode1.call();
// some code
}

Java Pass Method as Parameter

I am looking for a way to pass a method by reference. I understand that Java does not pass methods as parameters, however, I would like to get an alternative.
I've been told interfaces are the alternative to passing methods as parameters but I don't understand how an interface can act as a method by reference. If I understand correctly an interface is simply an abstract set of methods that are not defined. I don't want to send an interface that needs to be defined every time because several different methods could call the same method with the same parameters.
What I would like to accomplish is something similar to this:
public void setAllComponents(Component[] myComponentArray, Method myMethod) {
for (Component leaf : myComponentArray) {
if (leaf instanceof Container) { //recursive call if Container
Container node = (Container) leaf;
setAllComponents(node.getComponents(), myMethod);
} //end if node
myMethod(leaf);
} //end looping through components
}
invoked such as:
setAllComponents(this.getComponents(), changeColor());
setAllComponents(this.getComponents(), changeSize());
Edit: as of Java 8, lambda expressions are a nice solution as other answers have pointed out. The answer below was written for Java 7 and earlier...
Take a look at the command pattern.
// NOTE: code not tested, but I believe this is valid java...
public class CommandExample
{
public interface Command
{
public void execute(Object data);
}
public class PrintCommand implements Command
{
public void execute(Object data)
{
System.out.println(data.toString());
}
}
public static void callCommand(Command command, Object data)
{
command.execute(data);
}
public static void main(String... args)
{
callCommand(new PrintCommand(), "hello world");
}
}
Edit: as Pete Kirkham points out, there's another way of doing this using a Visitor. The visitor approach is a little more involved - your nodes all need to be visitor-aware with an acceptVisitor() method - but if you need to traverse a more complex object graph then it's worth examining.
In Java 8, you can now pass a method more easily using Lambda Expressions and Method References. First, some background: a functional interface is an interface that has one and only one abstract method, although it can contain any number of default methods (new in Java 8) and static methods. A lambda expression can quickly implement the abstract method, without all the unnecessary syntax needed if you don't use a lambda expression.
Without lambda expressions:
obj.aMethod(new AFunctionalInterface() {
#Override
public boolean anotherMethod(int i)
{
return i == 982
}
});
With lambda expressions:
obj.aMethod(i -> i == 982);
Here is an excerpt from the Java tutorial on Lambda Expressions:
Syntax of Lambda Expressions
A lambda expression consists of the following:
A comma-separated list of formal parameters enclosed in parentheses. The CheckPerson.test method contains one parameter, p,
which represents an instance of the Person class.Note: You
can omit the data type of the parameters in a lambda expression. In
addition, you can omit the parentheses if there is only one parameter.
For example, the following lambda expression is also valid:
p -> p.getGender() == Person.Sex.MALE
&& p.getAge() >= 18
&& p.getAge() <= 25
The arrow token, ->
A body, which consists of a single expression or a statement block. This example uses the following expression:
p.getGender() == Person.Sex.MALE
&& p.getAge() >= 18
&& p.getAge() <= 25
If you specify a single expression, then the Java runtime evaluates the expression and then returns its value. Alternatively,
you can use a return statement:
p -> {
return p.getGender() == Person.Sex.MALE
&& p.getAge() >= 18
&& p.getAge() <= 25;
}
A return statement is not an expression; in a lambda expression, you must enclose statements in braces ({}). However, you do not have
to enclose a void method invocation in braces. For example, the
following is a valid lambda expression:
email -> System.out.println(email)
Note that a lambda expression looks a lot like a method declaration;
you can consider lambda expressions as anonymous methods—methods
without a name.
Here is how you can "pass a method" using a lambda expression:
interface I {
public void myMethod(Component component);
}
class A {
public void changeColor(Component component) {
// code here
}
public void changeSize(Component component) {
// code here
}
}
class B {
public void setAllComponents(Component[] myComponentArray, I myMethodsInterface) {
for(Component leaf : myComponentArray) {
if(leaf instanceof Container) { // recursive call if Container
Container node = (Container)leaf;
setAllComponents(node.getComponents(), myMethodInterface);
} // end if node
myMethodsInterface.myMethod(leaf);
} // end looping through components
}
}
class C {
A a = new A();
B b = new B();
public C() {
b.setAllComponents(this.getComponents(), component -> a.changeColor(component));
b.setAllComponents(this.getComponents(), component -> a.changeSize(component));
}
}
Class C can be shortened even a bit further by the use of method references like so:
class C {
A a = new A();
B b = new B();
public C() {
b.setAllComponents(this.getComponents(), a::changeColor);
b.setAllComponents(this.getComponents(), a::changeSize);
}
}
Since Java 8 there is a Function<T, R> interface (docs), which has method
R apply(T t);
You can use it to pass functions as parameters to other functions. T is the input type of the function, R is the return type.
In your example you need to pass a function that takes Component type as an input and returns nothing - Void. In this case Function<T, R> is not the best choice, since there is no autoboxing of Void type. The interface you are looking for is called Consumer<T> (docs) with method
void accept(T t);
It would look like this:
public void setAllComponents(Component[] myComponentArray, Consumer<Component> myMethod) {
for (Component leaf : myComponentArray) {
if (leaf instanceof Container) {
Container node = (Container) leaf;
setAllComponents(node.getComponents(), myMethod);
}
myMethod.accept(leaf);
}
}
And you would call it using method references:
setAllComponents(this.getComponents(), this::changeColor);
setAllComponents(this.getComponents(), this::changeSize);
Assuming that you have defined changeColor() and changeSize() methods in the same class.
If your method happens to accept more than one parameter, you can use BiFunction<T, U, R> - T and U being types of input parameters and R being return type. There is also BiConsumer<T, U> (two arguments, no return type). Unfortunately for 3 and more input parameters, you have to create an interface by yourself. For example:
public interface Function4<A, B, C, D, R> {
R apply(A a, B b, C c, D d);
}
Use the java.lang.reflect.Method object and call invoke
First define an Interface with the method you want to pass as a parameter
public interface Callable {
public void call(int param);
}
Implement a class with the method
class Test implements Callable {
public void call(int param) {
System.out.println( param );
}
}
// Invoke like that
Callable cmd = new Test();
This allows you to pass cmd as parameter and invoke the method call defined in the interface
public invoke( Callable callable ) {
callable.call( 5 );
}
While this is not yet valid for Java 7 and below, I believe that we should look to the future and at least recognize the changes to come in new versions such as Java 8.
Namely, this new version brings lambdas and method references to Java (along with new APIs, which are another valid solution to this problem. While they still require an interface no new objects are created, and extra classfiles need not pollute output directories due to different handling by the JVM.
Both flavors(lambda and method reference) require an interface available with a single method whose signature is used:
public interface NewVersionTest{
String returnAString(Object oIn, String str);
}
Names of methods will not matter from here on. Where a lambda is accepted, a method reference is as well. For example, to use our signature here:
public static void printOutput(NewVersionTest t, Object o, String s){
System.out.println(t.returnAString(o, s));
}
This is just a simple interface invocation, up until the lambda1 gets passed:
public static void main(String[] args){
printOutput( (Object oIn, String sIn) -> {
System.out.println("Lambda reached!");
return "lambda return";
}
);
}
This will output:
Lambda reached!
lambda return
Method references are similar. Given:
public class HelperClass{
public static String testOtherSig(Object o, String s){
return "real static method";
}
}
and main:
public static void main(String[] args){
printOutput(HelperClass::testOtherSig);
}
the output would be real static method. Method references can be static, instance, non-static with arbitrary instances, and even constructors. For the constructor something akin to ClassName::new would be used.
1 This is not considered a lambda by some, as it has side effects. It does illustrate, however, the use of one in a more straightforward-to-visualize fashion.
Last time I checked, Java is not capable of natively doing what you want; you have to use 'work-arounds' to get around such limitations. As far as I see it, interfaces ARE an alternative, but not a good alternative. Perhaps whoever told you that was meaning something like this:
public interface ComponentMethod {
public abstract void PerfromMethod(Container c);
}
public class ChangeColor implements ComponentMethod {
#Override
public void PerfromMethod(Container c) {
// do color change stuff
}
}
public class ChangeSize implements ComponentMethod {
#Override
public void PerfromMethod(Container c) {
// do color change stuff
}
}
public void setAllComponents(Component[] myComponentArray, ComponentMethod myMethod) {
for (Component leaf : myComponentArray) {
if (leaf instanceof Container) { //recursive call if Container
Container node = (Container) leaf;
setAllComponents(node.getComponents(), myMethod);
} //end if node
myMethod.PerfromMethod(leaf);
} //end looping through components
}
Which you'd then invoke with:
setAllComponents(this.getComponents(), new ChangeColor());
setAllComponents(this.getComponents(), new ChangeSize());
If you don't need these methods to return something, you could make them return Runnable objects.
private Runnable methodName (final int arg) {
return (new Runnable() {
public void run() {
// do stuff with arg
}
});
}
Then use it like:
private void otherMethodName (Runnable arg){
arg.run();
}
Java-8 onwards
Java 8 onwards, you can provide the implementation of the abstract method of a functional interface (an interface that has only one abstract method) using a lambda expression and pass the same to a method as a parameter.
#FunctionalInterface
interface ArithmeticFunction {
public int calcualate(int a, int b);
}
public class Main {
public static void main(String args[]) {
ArithmeticFunction addition = (a, b) -> a + b;
ArithmeticFunction subtraction = (a, b) -> a - b;
int a = 20, b = 5;
System.out.println(perform(addition, a, b));
// or
System.out.println(perform((x, y) -> x + y, a, b));
System.out.println(perform(subtraction, a, b));
// or
System.out.println(perform((x, y) -> x - y, a, b));
}
static int perform(ArithmeticFunction function, int a, int b) {
return function.calcualate(a, b);
}
}
Output:
25
25
15
15
ONLINE DEMO
Learn more about it from Method References.
I didn't find any example explicit enough for me on how to use java.util.function.Function for simple method as parameter function. Here is a simple example:
import java.util.function.Function;
public class Foo {
private Foo(String parameter) {
System.out.println("I'm a Foo " + parameter);
}
public static Foo method(final String parameter) {
return new Foo(parameter);
}
private static Function parametrisedMethod(Function<String, Foo> function) {
return function;
}
public static void main(String[] args) {
parametrisedMethod(Foo::method).apply("from a method");
}
}
Basically you have a Foo object with a default constructor. A method that will be called as a parameter from the parametrisedMethod which is of type Function<String, Foo>.
Function<String, Foo> means that the function takes a String as parameter and return a Foo.
The Foo::Method correspond to a lambda like x -> Foo.method(x);
parametrisedMethod(Foo::method) could be seen as x -> parametrisedMethod(Foo.method(x))
The .apply("from a method") is basically to do parametrisedMethod(Foo.method("from a method"))
Which will then return in the output:
>> I'm a Foo from a method
The example should be running as is, you can then try more complicated stuff from the above answers with different classes and interfaces.
Java do have a mechanism to pass name and call it. It is part of the reflection mechanism.
Your function should take additional parameter of class Method.
public void YouMethod(..... Method methodToCall, Object objWithAllMethodsToBeCalled)
{
...
Object retobj = methodToCall.invoke(objWithAllMethodsToBeCalled, arglist);
...
}
I did not found any solution here that show how to pass method with parameters bound to it as a parameter of a method. Bellow is example of how you can pass a method with parameter values already bound to it.
Step 1: Create two interfaces one with return type, another without. Java has similar interfaces but they are of little practical use because they do not support Exception throwing.
public interface Do {
void run() throws Exception;
}
public interface Return {
R run() throws Exception;
}
Example of how we use both interfaces to wrap method call in transaction. Note that we pass method with actual parameters.
//example - when passed method does not return any value
public void tx(final Do func) throws Exception {
connectionScope.beginTransaction();
try {
func.run();
connectionScope.commit();
} catch (Exception e) {
connectionScope.rollback();
throw e;
} finally {
connectionScope.close();
}
}
//Invoke code above by
tx(() -> api.delete(6));
Another example shows how to pass a method that actually returns something
public R tx(final Return func) throws Exception {
R r=null;
connectionScope.beginTransaction();
try {
r=func.run();
connectionScope.commit();
} catch (Exception e) {
connectionScope.rollback();
throw e;
} finally {
connectionScope.close();
}
return r;
}
//Invoke code above by
Object x= tx(() -> api.get(id));
Example of solution with reflection, passed method must be public
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
public class Program {
int i;
public static void main(String[] args) {
Program obj = new Program(); //some object
try {
Method method = obj.getClass().getMethod("target");
repeatMethod( 5, obj, method );
}
catch ( NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
System.out.println( e );
}
}
static void repeatMethod (int times, Object object, Method method)
throws IllegalAccessException, InvocationTargetException {
for (int i=0; i<times; i++)
method.invoke(object);
}
public void target() { //public is necessary
System.out.println("target(): "+ ++i);
}
}
Use the Observer pattern (sometimes also called Listener pattern):
interface ComponentDelegate {
void doSomething(Component component);
}
public void setAllComponents(Component[] myComponentArray, ComponentDelegate delegate) {
// ...
delegate.doSomething(leaf);
}
setAllComponents(this.getComponents(), new ComponentDelegate() {
void doSomething(Component component) {
changeColor(component); // or do directly what you want
}
});
new ComponentDelegate()... declares an anonymous type implementing the interface.
Here is a basic example:
public class TestMethodPassing
{
private static void println()
{
System.out.println("Do println");
}
private static void print()
{
System.out.print("Do print");
}
private static void performTask(BasicFunctionalInterface functionalInterface)
{
functionalInterface.performTask();
}
#FunctionalInterface
interface BasicFunctionalInterface
{
void performTask();
}
public static void main(String[] arguments)
{
performTask(TestMethodPassing::println);
performTask(TestMethodPassing::print);
}
}
Output:
Do println
Do print
I'm not a java expert but I solve your problem like this:
#FunctionalInterface
public interface AutoCompleteCallable<T> {
String call(T model) throws Exception;
}
I define the parameter in my special Interface
public <T> void initialize(List<T> entries, AutoCompleteCallable getSearchText) {.......
//call here
String value = getSearchText.call(item);
...
}
Finally, I implement getSearchText method while calling initialize method.
initialize(getMessageContactModelList(), new AutoCompleteCallable() {
#Override
public String call(Object model) throws Exception {
return "custom string" + ((xxxModel)model.getTitle());
}
})
I appreciate the answers above but I was able to achieve the same behavior using the method below; an idea borrowed from Javascript callbacks. I'm open to correction though so far so good (in production).
The idea is to use the return type of the function in the signature, meaning that the yield has to be static.
Below is a function that runs a process with a timeout.
public static void timeoutFunction(String fnReturnVal) {
Object p = null; // whatever object you need here
String threadSleeptime = null;
Config config;
try {
config = ConfigReader.getConfigProperties();
threadSleeptime = config.getThreadSleepTime();
} catch (Exception e) {
log.error(e);
log.error("");
log.error("Defaulting thread sleep time to 105000 miliseconds.");
log.error("");
threadSleeptime = "100000";
}
ExecutorService executor = Executors.newCachedThreadPool();
Callable<Object> task = new Callable<Object>() {
public Object call() {
// Do job here using --- fnReturnVal --- and return appropriate value
return null;
}
};
Future<Object> future = executor.submit(task);
try {
p = future.get(Integer.parseInt(threadSleeptime), TimeUnit.MILLISECONDS);
} catch (Exception e) {
log.error(e + ". The function timed out after [" + threadSleeptime
+ "] miliseconds before a response was received.");
} finally {
// if task has started then don't stop it
future.cancel(false);
}
}
private static String returnString() {
return "hello";
}
public static void main(String[] args) {
timeoutFunction(returnString());
}

Categories

Resources