I'm basically trying to create a static method that will serve as a wrapper for any method I pass and will execute something before and after the actual execution of the method itself. I'd prefer to do it using Java 8 new coding style. So far I have a class that has a static method, but I'm not sure what the parameter type should be so it can take any method with any type of parameter and then execute it. Like i mentioned I want to do some stuff before and after the method executes.
For example: executeAndProcess(anyMethod(anyParam));
Your method can accept a Supplier instance and return its result:
static <T> T executeAndProcess(Supplier<T> s) {
preExecute();
T result = s.get();
postExecute();
return result;
}
Call it like this:
AnyClass result = executeAndProcess(() -> anyMethod(anyParam));
Related
Groovyc: [Static type checking] - Cannot find matching method io.swagger.client.util.EmUtil#addLobList(java.lang.Object, java.lang.Object). Please check if the declared type is correct and if the method exists.
I am calling this function in a static block in groovy, as shown below:
static {
Arrays.asList(LOBEnum.values()).forEach {lob -> EmUtil.getInstance().addLobList(lob.name(), lob.getLob())}
EmUtil.getInstance().setPrefix("CCB_Reference_Data_")
EmUtil.getInstance().init()
}
This calls a java function, as shown below:
public void addLobList(String lob, String licenseLob) {
lobList.add(lob);
lobLicenseList.add(licenseLob);
}
It looks like lob.name() and lob.getLob() each have a return type of Object. If you want to use the return values of those methods as parameters to your addLobList method, the static type checker needs to make sure those are String instance. You can cast those with (String). Alternatively, you could change the return value of those methods to String.
I am new to java and started working on constructors. I am seeing few examples where constructor is passed as parameter to a Method. Please tell me what happens when a constructor is passed as a parameter to a method..or suggest me some links where can i get enough knowledge about using constructors
Depending on the purpose why do you need to pass the constructor you may consider passing the instance of Supplier instead (JavaDoc - https://docs.oracle.com/javase/8/docs/api/java/util/function/Supplier.html).
For example you have a method which suppose to create an account and fill everything in it. You can make this method to accept Supplier as a parameter:
public Account createNewAccount(Supplier<Account> accountConstructor) {
var account = accountConstructor.get();
account.fillEverything();
return account;
}
And after that pass constructor to this method either using lambda:
createNewAccount(() -> new UserAccount());
Or using method reference:
createNewAccount(UserAccount::new);
Both variants are working.
Constructors can be passed as arugments to methods using a method reference, somewhat like a function pointer in C++.
See: http://www.baeldung.com/java-8-double-colon-operator
This can be a Function type with one argument or a BiFunction type with two arguments, either way its a lambda returning a class of the type it constructs.
Like Turing85 said though I don't think this is what you want. Passing constructors as parameters is a pretty niche use case. If you just want information on constructors,
https://docs.oracle.com/javase/tutorial/java/javaOO/constructors.html
Here is an example class that holds two constructors as instance variables and invokes one of them when the constructItem method is called. The first constructor is stored as a Supplier that returns an object of type S and the second takes a Function that takes type T and returns type S.
public class ConstructorWrapper<T, S> {
private final Supplier<S> construct;
private final Function<T, S> constructFromObject;
public ConstructorWrapper(Supplier<S> constructWithNothing, Function<T, S> constructWithObject) {
this.construct = constructWithNothing;
this.constructFromObject = constructWithObject;
}
public S constructItem(T k) {
if (k != null) return this.construct.get();
else return constructFromObject.apply(k);
}
}
We can use the class like this to wrap creation of ArrayLists from Sets. x is created by invoking the constructor with no parameters and y is created by invoking the constructor with one parameter.
ConstructorWrapper<Set, ArrayList> setToArrayList = new ConstructorWrapper<>(ArrayList::new, ArrayList::new);
ArrayList x = setToArrayList.constructItem(null);
ArrayList y = setToArrayList.constructItem(new HashSet<>());
Or like this to wrap creation of Sets from ArrayLists:
ConstructorWrapper<ArrayList, HashSet> arrayListsToSets = new ConstructorWrapper<>(HashSet::new, HashSet::new);
HashSet x = arrayListsToSets.constructItem(null);
HashSet y = arrayListsToSets.constructItem(new ArrayList<>());
I used raw ArrayLists and Sets because I didn't want to clutter the code with more generics
How can I call a method that is passed on through a parameter in a method in Java 8?
Small example I have a method like that:
void output(String text) {
System.out.println(text)
}
Now I want to pass that method to another class which should call output and set something for text. Is that possible?
The class you want to pass the function to must take a parameter of type Consumer<String>. This class represents a function that takes a parameter of some type (String in this case), and has return type void. A Consumer has a method accept that takes the parameter and calls the function.
You can create you class like this:
class Test {
Test(Consumer<String> consumer) {
consumer.accept("This is a string!");
}
}
Now, when you want to instantiate this class, you need to pass your function to it like this:
Test t = new Test(this::output);
The :: notation is called a method reference. The this (before the colons) means that the method is located in the object you're in. It can be changed to, for example, MyClass::output if it is a static method on MyClass, or myObject::output if it is a method on the object myObject.
I want to invoke a method using eclipse AST.
I have the MethodDeclarion of the method to be invoked. How can I invoke this method passing appropriate DUMMY/ default arguments.
i.e.
public void setStr (String str) { ... };
public void setSomeObj (SomeObj obj ) { ... };
Suppose I have MethodDeclarions of the above methods.
Now I want to create a MethodInvocation like the following.
setStr("some dummy value");
setSomeObj(new SomeObj());
The difficulty I have is generating the DUMMY/ default arguments for method invocation.
Please help
MethodInvocation s;
s.arguments().add(...);
if you want to add an object that is part of the existing AST it needs to be:
....add((Cast)r.createCopyTarget(Object));
Cast = you will probaby have to cast it to a certain type, eclipse will tell you which.
In Java, or Groovy, say I have a String array like
myArray = ["SA1", "SA2", "SA3", "SA4"]
I want to call a different function based off of each string.
class Myclass{
public static void SA1() {
//doMyStuff
}
public static void SA2() {
//doMyStuff
}
...etc
}
I would love to be able to loop through my array and call the functions that they pertain to without having to compare the string or make a case statement. For example is there a way to do something like the following, I know it doesn't currently work:
Myclass[myArray[0]]();
Or if you have suggestions of another way I can structure something similar.
In groovy you can do:
Myclass.(myArray[0])()
In Java you can do:
MyClass.class.getMethod(myArray[0]).invoke(null);
In Groovy, you can use a GString for dynamic method invocation:
myArray.each {
println Myclass."$it"()
}
You can, for instance, declare an interface such as:
public interface Processor
{
void process(String arg);
}
then implement this interface, for example in singletons.
Then create a Map<String, Processor> where keys are your strings, values are implementations and, when invoking:
Processor p = theMap.containsKey(theString)
? theMap.get(theString)
: defaultProcessor;
p.process(theString);
I suggest you look at Reflection APIs, to call methods at runtime
check Reflection docs
Class cl = Class.forName("/* your class */");
Object obj = cl.newInstance();
//call each method from the loop
Method method = cl.getDeclaredMethod("/* methodName */", params);
method.invoke(obj, null);