How refactor the method? - java

There is a given method. How can we refactor it?
public void foo(Factor o){
if(o.matches(constant1)){
method1();
}else if(o.matches(constant2)){
method2();
}
}else if(o.matches(constant3)){
method3();
}
....
}

This is something called a code smell. You would want to use what's called the "command pattern" which is a design pattern to refactor this code. On mobile now, will update with an example when I get to my desk today.
Edit: Here we go.
So the command pattern is a design pattern used for this exact scenario. What you need to first do is create a command Interface.
public interface MyCommand {
public void execute();
}
Great. Next you create Command objects that hold all of your method data.
public class Method1Command implements MyCommand {
public MyVariable var;
public Method1Command(<your arguments to create method>)
{
// instantiate your command
}
public void execute()
{
// what your current method1() is;
}
}
And then you just create some kind of private class in your Main to create a HashMap of all of the commands, keyed with the value of "ConstantX."
private static Map<String, MyCommand> getMyCommands()
{
Map<String, MyCommand> commandList = new HashMap<String, MyCommand>();
MyCommand c;
c = new Method1Command();
commandList.put("constant1", c);
c = new Method2Command();
commandList.put("constant2", c);
c = new Method3Command();
commandList.put("constant3", c);
return commandList();
}
Then, in the refactored method you would simply do the following:
public void foo(Factor o)
{
cl.get(o).execute();
}
This, however, assumes that o has some kind of toString method inside it, or if you have some method inside of o that you use to get the command it would be something like this: cl.get(o.getMyCommand()).execute();

You can make an array containing the constants, and a Map containing constant-string pairs (String is the name of the method), use reflection and do something like:
public void foo(Factor o) {
for(int i = 0; i < constans.length; i++) {
if(o.matches(constant)) {
Method method =
YourClass.class.getMethod(myMap.get(constant), null);
method.invoke(null);
}
}
}

Related

Execute a function "before each" method of the same class in java

I have several methods in a class that require a boolean to be set to true in order to execute correctly.
I could write the if statement in each method, but it is not convenient if I or someone else wants to ad another method. I or he could forget about the check.
Is there a way in java to execute a method before each other methods (exactly like JUnit does with #BeforeEach ) in a class ?
Edit: Lots of very interesting techniques/answers/concepts proposed. I'll be in touch when I've understood them. Thanks.
Lets make a method turnBooleanTrue() where effectively the boolean is set to true in order for the method to be execute correctly.
Then, you can write up your very own InvocationHandler that would intercept calls to your objects, and then reflectively (using reflection API) invoke first the turnBooleanTrue() method followed by the method to which the call was made.
Will look something like this
public class MyClassInvocationHandler implements InvocationHandler {
// initiate an instance of the class
MyClass myClass = new MyClassImpl();
#Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// look up turnBooleanTrue() method
Method turnBooleanTrue = myClass.getClass().getMethod("turnBooleanTrue");
// invoke the method
turnBooleanTrue.invoke(...); // toggle the boolean
// invoke the method to which the call was made
// pass in instance of class
Object returnObj = method.invoke(myClass, args);
return returnObj;
}
EDIT
Added some lines to have an object of MyClass initialized. You need something to invoke the method on and maintain the state. Changed util to myClass in the code example above.
Considering my use case, it was a bit overkill to use AOP or other concepts. So I basically did a check in each functions.
With AOP, this is how what you need would look:
// wraps around all methods in your class that have a boolean parameter
#Around(value = "#target(*..YourClass) && args(yourBool)", argNames = "jp,yourBool")
Object scheduleRequest(ProceedingJoinPoint jp, boolean yourBool) {
if (yourBool) {
jp.proceed(yourBool);
} else {
throw new RuntimeException("cannot execute this method!");
}
}
This would handle the case that the method take the boolean you say needs evaluation as its (only) parameter. If it comes from a different source, you may need to wire it into the aspect somehow, that depends on your overall design.
I suggest a simple solution by dividing your workflow in four components.
You have an interface you use to execute commands.
You have an interface that defines which commands you can use.
You have one wrapper that analyzes your boolean value.
You have an implementation of the work performing class, that implements the second interface.
Your wrapper initialize the worker.
Your wrapper exposes an action performing command that accepts the executing interface.
if the boolean is true, pass the worker to the executing interface work method.
the executing interfaces work method calls the work function on the command instance interface, the worker.
See it online: https://ideone.com/H6lQO8
class Ideone
{
public static void main (String[] args) throws java.lang.Exception
{
WorkDistributer wd = new WorkDistributer();
wd.enable();
wd.performAction((w) -> {w.printHello();});
wd.disable();
wd.performAction((w) -> {w.printHello();});
wd.enable();
wd.performAction((w) -> {w.printAnswer();});
wd.disable();
wd.performAction((w) -> {w.printAnswer();});
}
}
class WorkDistributer
{
private boolean enabled = false;
private ActionPerformer worker;
public WorkDistributer() {
this.worker = new Worker();
}
public void enable() {
enabled = true;
}
public void disable() {
enabled = false;
}
public void performAction(ActionCommand command) {
if(this.enabled) {
command.run(this.worker);
}
}
}
class Worker implements ActionPerformer {
public void printHello() {
System.out.println("hello");
}
public void printAnswer() {
System.out.println(21 * 2);
}
}
interface ActionPerformer {
public void printHello();
public void printAnswer();
}
interface ActionCommand {
public void run(ActionPerformer worker);
}

Putting a Method in an array

So I want to make an array that has methods in it. For example:
public static void givePointBoost(){
points += 30};
or
public static void giveSword(){
Actions.giveItems(Items.diamond_sword);
Actions.givePotion(Potions.slowness);};
As you can see, both of these methods are voids. What I want to do is have an array that has all these voids in it so that I can pick a random method out of it later on. But I can't put it into an array because It says that I can't have an array of voids. When I try to make it an array of objects, It says that it can't switch from object to void. So my question is:
How do you get methods inside of Arrays?
In Java, you do not have delegates or function pointers, which you can store in collections or arrays like objects, so you have to employ the Command Pattern to achieve this. Basically, you wrap a method in an object that you pass on. The receiver can then access the method via the object.
Create a command interface:
interface ICommand {
public void execute();
}
Wrap a method (or multiple) in a class via inheritance...
class SpecificCommand implements ICommand {
public void execute() {
// Do something...
}
}
...or wrap existing methods directly in an anonymous class:
class SomeClass {
private void someMethod(int someValue) {
// Some stuff...
}
public static void main(String[] args) {
List<ICommand> commands = new ArrayList<>();
// Do something...
// Add command directly
ICommand command = new ICommand() {
#Override
public void execute() {
someMethod(42);
}
}
// Do something....
}
}
Call the commands from the list in a loop (or single):
for (ICommand command : commands) {
command.execute();
}
Let's sort things out.
Arrays in Java can only contain objects or primitives.
Collections in Java can only contain objects.
What you're looking for is called a Command Pattern.
https://www.tutorialspoint.com/design_pattern/command_pattern.htm
You'll have a list of objects, each of them with single method, let's say "execute". With polymorphism, each of this objects will do something different.
Here's an example:
import java.util.ArrayList;
import java.util.List;
public class CommandPatternExample {
public static void main(String[] args) {
List<Command> commands = new ArrayList<>();
commands.add(new GiveBoostCmmand("knight"));
commands.add(new GiveItemCommand("sword", "knight"));
for (int i = 0; i < 3; i++) {
commands.get((int)(Math.random() * commands.size())).execute();
}
}
public interface Command {
void execute();
}
static class GiveBoostCmmand implements Command {
private String targetName;
public GiveBoostCmmand(String targetName) {
this.targetName = targetName;
}
public void execute() {
System.out.println("Boosting " + this.targetName);
}
}
static class GiveItemCommand implements Command {
private String itemName;
private String targetName;
public GiveItemCommand(String itemName, String targetName) {
this.itemName = itemName;
this.targetName= targetName;
}
public void execute() {
System.out.println("Giving " + this.itemName + " to " + this.targetName);
}
}
}
Are you trying to say you want the result of the method to be added to the array?
As far as i know, i don't think you can put a method inside an array.
What you could do is create an interface, and provide implementations and then add those objects to an array. That way you could pick a random object and call the method defined in the interface.
The main question is Why do you need methods in an array?
The other solutions using the Command pattern are a great solution. But seeing your code I believe that you also should put that pattern in a specialized class whose purpose will be to initialize the pool of possible actions and select one at random when you need to.
Which would translate to the following UML
|RandomActionCaller |
|------------------------|
|- List<Command> commands|
|------------------------|
|+ selectRandomEffect() |
In the constructor you prepare the basic list of possible outcome, please refer to the other answers about the Command pattern. Maybe also add a method to add more commands to the list of commands from the outside of the class, this can be usefull.
The select random effect method would only select a random number between 0 and commands.size()-1, get the command instance and execute it. If you need to execute it somewhere else in your code just return it from the select random effect method.

JAVA: Call class method based on value of variable

I am working on a project in java and am quite new to the language and OOP. My dilema is that I want to carry out a task/function from a specific class based on the value of a variable.
This is kind of what I am trying to achieve.
class mainClass{
String option;
public static void main(String[] args) {
mainClass main = new mainClass();
}
mainClass(){
secondClass sC = new secondClass();
thirdClass tC = new thirdClass();
switch (option){
case "1" :
sC.doSomething();
case "2" :
tC.doSomething();
}
}
}
class secondClass{
void doSomething(){
System.out.println("1");
}
}
class thirdClass{
void doSomething(){
System.out.println("2");
}
}
The reason I don't want to do this, is because if I want to add a fourth, fifth, sixth class etc... I would have to update the switch.
I tried using a hashmap. Where I assigned secondClass the key of "1". But then I would have to cast the object, but this brings me back to the original headache of not knowing what class would need to be called in advance.
So then I tried using a hashmap like this,
HashMap<String, Object> map = new HashMap<String, Object>();
Which I could then do map.get("1") but then now I can't call any of the methods for the class in question.
If I need to use a large switch statement I will, but I am actively seeking a more efficient alternative.
You were right to use a Map but you were also right to balk at casting. However, nowadays with generics you can get around all that:
interface DoesSomething {
// An object implementing this interface does something.
public void doSomething();
}
// Class that does something.
class FirstClass implements DoesSomething {
#Override
public void doSomething() {
// What FirstClass does.
}
}
// Another class that does something.
class SecondClass implements DoesSomething {
#Override
public void doSomething() {
// What SecondClass does.
}
}
// How I know what to do. Map the string to a DoesSomethng.
Map<String, DoesSomething> whatToDo = new HashMap<>();
{
// Populate my map.
whatToDo.put("1", new FirstClass());
whatToDo.put("2", new SecondClass());
}
public void doSomethingDependingOnSomething(String something) {
// Look up the string in the map.
DoesSomething toDo = whatToDo.get(something);
// Was it in there?
if (toDo != null) {
// Yes! Make it do it's thing.
toDo.doSomething();
}
}
If you want to avoid using Reflection (wich is discouraged here), you should consider a simple SAM-Interface:
public interface Doable { public void doSomething(); }
and have all classes implement the interface (no other changes required in these classes) and having a Map<String, Doable> and calling
if (map.containsKey(option)) map.get(option).doSomething();
// Or (may be a little faster)
Doable opt = map.get(option);
if (opt != null) opt.doSomething();
If your implementations have different methods, you'll most likely be bound to use Reflection to get the declared methods and compare by String.

Class for Strong References in Java, for anonymous classes

I want a hard reference class in my Java code, but, of course, there isn't one. Is there some other way to do what I want, or should I make my own class?
This comes up with anonymous classes in methods where I want the anonymous class to set the return value for the method.
For example, given
interface Greeting {
void greet();
}
I want code like the following:
// Does not compile
static void hello(final String who) {
String returnValue;
Greeting hello = new Greeting() {
public void greet() {
returnValue = "hello" + who;
}
};
hello.greet();
System.out.println(returnValue);
}
I can fake it using a list:
static void hello(final String who) {
final List<String> returnValue = new ArrayList<String>();
Greeting hello = new Greeting() {
public void greet() {
returnValue.add("hello" + who);
}
};
hello.greet();
System.out.println(returnValue.iterator().next());
}
But I want to not use a list. I can write a StrongReference class that solves this:
static class StrongReference<T> {
private T referent;
public void set(T referent) {
this.referent = referent;
}
public T get() {
return referent;
}
}
which makes my method clearer:
static void hello(final String who) {
final StrongReference<String> returnValue = new StrongReference<String>();
Greeting hello = new Greeting() {
public void greet() {
returnValue.set("hello" + who);
}
};
hello.greet();
System.out.println(returnValue.get());
}
For my contrived example, I could have greet() return a String, but I'm working with much more complex classes, where the setting is deep within a database call that the base class manages. The instances have many different types they want to return, so I've just been using the List trick.
My questions are: Is there a better way to do this? What's wrong with my StrongReference class? Has anyone written a StrongReference in a library somewhere?
If you want something from the standard API, perhaps an AtomicReference would do?
It has void set(V value) and a V get() methods. Unless you have multiple threads involved, just see the synchronization mechanism as a bonus ;-)
A common idiom
final String[] result = { null };
result[0] = ...;
Looks good but I think you should make some kind of synchronization since another thread might set the value.

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