I have 5 different methods like this
public void met1(){}
public void met2(){}
public void met3(){}
public void met4(){}
public void met5(){}
I want to call this method from 1 to 5 is there any convinient way to do this.
I don't want to call one by one or I don't want to put method call inside other method.
How Can I do this??
I believe you could do it with reflection with something like:
YourClass classInstance = new YourClass();
for (int i = 1; i < 6; i++) {
Method yourMethod = YourClass.class.getMethod("met" + i);
method.invoke(instance);
}
Haven't tested it out, so no guarantees.
Have you looked into fluent design patterns? http://www.javacodegeeks.com/2013/01/fluent-object-creation.html
Example would be something like this:
myObject.met1().met2().met3().met4().met5().result();
You can use the Execute Around Method pattern.
public class Resource {
private Resource(){}
public void opc1(){
System.out.println("Opc1");
// use can use cascade pattern( return this)
}
public void opc2(){
System.out.println("Opc2");
// use can use cascade pattern( return this)
}
public void opc3(){
System.out.println("Opc3");
// use can use cascade pattern( return this)
}
public void closeResource(){
System.out.println("Release resource");
}
public static void use(Consumer<Resource> consumer){
Resource resource =new Resource();
consumer.accept(resource);
resource.closeResource(); // force to execute closeResource method
}
public static void main(String[] args) {
Resource.use(resource -> {
resource.opc1();
resource.opc3();
resource.opc2();
});
}
}
More info at https://agiledeveloper.com/
You could do this with reflection as other answers have previously mentioned. Reflection is generally avoided if possible.
In reality the most common design pattern to address your concern would be Chain of Responsibility.
http://en.wikipedia.org/wiki/Chain-of-responsibility_pattern
The only way to call methods by name is through reflection. See this article for how to do this:
How do I invoke a Java method when given the method name as a string?
Something like this should work:
for (int i = 1; i < 6; i++){
java.lang.reflect.Method method;
try {
method = this.getClass().getMethod("met" + i);
method.invoke(this);
} catch (SecurityException e) {
// ...
} catch (NoSuchMethodException e) {
// ...
}
}
Related
So, I have the following classes:
public class MainClass{
public void run(String infoOne, String infoTwo, String infoThree, String infoFour, String infoFive, String infoSix){
SomeClass someClass = new SomeClass();
someClass.runSomeMethod();
someClass.runSomeMethodTwo( infoOne);
someClass.runSomeMethodThree( infoThree, infoOne, infoSix);
someClass.runSomeMethodFour( infoTwo, infoFive);
someClass.runSomeMethodFive(infoThree, infoFive, infoOne, infoSix);
}
}
public class SomeClass{
public boolean runSomeMethod(){
// do something
}
public boolean runSomeMethodTwo(String arg){
// do something
}
public boolean runSomeMethodThree(String argOne, String argTwo, String argThree){
// do something
}
public boolean runSomeMethodFour(String argOne, String argTwo){
// do something
}
public boolean runSomeMethodFive(String argOne, String argTwo, String argThree, String argFour){
// do something
}
}
As you can see it's a bunch of methods taking only Strings as parameters (but a different amount every time). What I want now is to wrap each single method in a try catch block and log some results. To do that I wanted to put a method in between that handles the logging:
log(SomeClass::runSomeMethodFour);
public void log(????? method, String...args){
try{
if(method.execute(args);
System.out.println("Success!");
} else {
System.out.println("Failed to execute!");
}
} catch (Exception e){
e.printStackTrace();
}
}
Is this possible in some way? To pass a dynamic number of arguments to a lambda function? Or could I do something with generics?
There is no need to create a complicated Reflection-based solution. Your problems stem from the unnecessary attempt to separate the method and the parameter arguments, instead of just encapsulating the entire action like
public class MainClass {
public void run(String infoOne, String infoTwo, String infoThree,
String infoFour, String infoFive, String infoSix) {
SomeClass someClass = new SomeClass();
log(() -> someClass.runSomeMethod());
log(() -> someClass.runSomeMethodTwo(infoOne));
log(() -> someClass.runSomeMethodThree(infoThree, infoOne, infoSix));
log(() -> someClass.runSomeMethodFour(infoTwo, infoFive));
log(() -> someClass.runSomeMethodFive(infoThree, infoFive, infoOne, infoSix));
}
public void log(BooleanSupplier method) {
try {
if(method.getAsBoolean()) {
System.out.println("Success!");
} else {
System.out.println("Failed to execute!");
}
} catch (Exception e ){
e.printStackTrace();
}
}
}
For the work of the log method, only the boolean return value is relevant, which matches the functional signature of BooleanSupplier.
JLS described Method Reference Expression:
The compile-time declaration of a method reference is the method to which the expression refers. In special cases, the compile-time declaration does not actually exist, but is a notional method that represents a class instance creation or an array creation. The choice of compile-time declaration depends on a function type targeted by the expression, just as the compile-time declaration of a method invocation depends on the invocation's arguments.
A method reference expression is compatible in an assignment context, invocation context, or casting context with a target type T if T is a functional interface type (§9.8) and the expression is congruent with the function type of the ground target type derived from T.
the method reference expression must be assign an exactly Function Interface at compile time. and Function Interface is a SAM Interface. so you can't bind a method handler dynamically by method reference expression at runtime.
but you can using reflection or invoke api to achieve it.
let see each method expression refer to a Function Interface in your SomeClass results in refers to different Function Interface type:
SomeClass it = new SomeClass();
BooleanSupplier first1 = it::runSomeMethod;//bound
Predicate<SomeClass> first2 = SomeClass::runSomeMethod;//unbound
Predicate<String> second1 = it::runSomeMethodTwo;//bound
BiPredicate<SomeClass, String> second2 = SomeClass::runSomeMethodTwo;//unbound
...
Hearing about "reflection" as a comment by Oliver Charlesworth I came up with the following solution:
public class Test {
static Test testLogger = new Test(); //This should be another class ofcourse, but it doesn't matter for this example
public static void main(String[] args) throws NoSuchMethodException, SecurityException{
Test test = new Test();
run(test, "something", "hi", "hai", "blaa");
}
public static void run(Object pageObjectModel, String methodName, String...arguments){
Class<String>[] args = new Class[arguments.length];
Arrays.fill(args, String.class);
try {
testLogger.log(pageObjectModel, pageObjectModel.getClass().getMethod(methodName, args), arguments);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
}
}
private void log(Object pageObjectModel, Method method, String...arguments) {
try {
if((Boolean)method.invoke(pageObjectModel, (Object[])arguments)){
System.out.println("Success!");
} else {
System.out.println("Fail!");
}
} catch (Exception e){
e.printStackTrace();
}
}
public boolean something(String one, String two, String three){
System.out.println(one+", "+two+", "+three);
return true;
}
}
This seems to be perfect for what I'm trying to achieve. Although I don't really like reflection due to having bad experiences with it (giving problems with obfuscated code) I think it's fine for this project.
Thanks for helping me in the right direction!
Im beginner JAVA developer. Here is a method:
private Method getSomething()
{
for (Method m : getClass().getDeclaredMethods())
{
return m;
}
return notFound;
}
private void notFound()
{
throw new Exception();
}
it doesnt matter what it does - if it finds something, then returns a Method - if not, the notFound() method itself should be returned. So the hot spot is at the return notFound; line: if I use return notFound(); then it returns its value, not the method itself. I want something like a reference/pointer. So getSomething() returns something what can be called, and if the returned method is used wrong, it should trigger that Exception - so its not an option to replace return notFound; with throw new Exception(); !
Or the 2nd option is to create a lambda method....
You need to call
this.getClass().getMethod("notFound")
to get the notFound method of the current/this object's class.
So just do this:
return this.getClass().getMethod("notFound");
More details here:
Class.getMethod
EDIT:
You can retrieve i.e. get and call private methods too via reflection.
Here is an example.
import java.lang.reflect.Method;
public class Test001 {
public static void main(String[] args) throws Exception {
Test002 obj = new Test002();
Method m = obj.getClass().getDeclaredMethod("testMethod", int.class);
m.setAccessible(true);
m.invoke(obj, 10);
m.invoke(obj, 20);
System.out.println(m.getName());
}
}
class Test002 {
private void testMethod(int x){
System.out.println("Hello there: " + x);
}
}
You need to use reflection to achieve this:
http://docs.oracle.com/javase/tutorial/reflect/
e.g. to get all methods of a given class:
Class aClass = ...//obtain class object
Method[] methods = aClass.getMethods();
I have a large number of methods that need to be applied to each member of a given arrayList. The problem is that I'm at compile time uncertain which methods need to be applied to the arrayList and applying all of them each time (with a check) would be to costly (realtime application). So I'm now looking for a way to give the list a number of methods (a la function programming) and have them run. I know I could create special classes where each class uses only a uses a single method on each of it's members but there are roughly 50 methods so that would quickly escalate into 50 different classes. Which would add a lot of unnecessary complexity to the project. Is there another way?
So what I'm looking for is something like this:
public void runMethode(Function f,ArrayList<ObjectWithF> al){
for(ObjectWithF o:al){
o.f();
}
}
Does such a thing exist in java? Or am I going to have to either call all 50 methods or create 50 different classes? Or would a wrapper pattern work here?
In Java 8, this functionality is provided via the Stream#forEach(Consumer) method in a very convenient form.
If you don't have Java 8 yet, then you can create an interface, and create instances of anonymous classes implementing this interface. This is a bit more verbose, but still better than 50 named classes.
It may be beneficial to design this interface in a way that is structurally equal to the Consumer interface that is used in Java 8, so that it may simply be changed to use the Java 8 version once you do the update.
This example shows a comparison of both approaches:
import java.util.ArrayList;
import java.util.List;
class Person
{
void sayHello()
{
System.out.println("Hello from "+this);
}
void sayGoodbye()
{
System.out.println("Goodbye from "+this);
}
}
// This interface already exists as java.util.function.Consumer in Java 8
interface Consumer<T>
{
void accept(T t);
}
public class ForEachTest
{
public static void main(String[] args)
{
List<Person> persons = new ArrayList<Person>();
for (int i=0; i<5; i++)
{
persons.add(new Person());
}
runJava8(persons);
runJava7(persons);
}
private static void runJava8(List<Person> persons)
{
persons.stream().forEach(Person::sayHello);
persons.stream().forEach(Person::sayGoodbye);
}
private static void runJava7(List<Person> persons)
{
runMethodJava7(persons, new Consumer<Person>()
{
#Override
public void accept(Person person)
{
person.sayHello();
}
});
runMethodJava7(persons, new Consumer<Person>()
{
#Override
public void accept(Person person)
{
person.sayGoodbye();
}
});
}
public static void runMethodJava7(
List<Person> persons, Consumer<? super Person> consumer)
{
for(Person person : persons)
{
consumer.accept(person);
}
}
}
reflect can help.
see the code blow :
String obj = "abc";
String methodName = "toString";
try {
Method method = obj.getClass().getMethod("toString");
System.out.println(method.invoke(obj));
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
we have a obj, and given a method, we can run this method on that object.
And, you can also consider define a interface, and all your objects in the list implements the interface. and iterate the list, call those methods which defined in the interface.
As of Java 8, use may use Consumer class:
public void runMethod(Consumer<ObjectWithF> consumer, ArrayList<ObjectWithF> al) {
for (ObjectWithF o : al) {
consumer.accept(o);
}
}
...
// for example
runMethod (o -> System.out.println (o), listOfObjectsWithF);
// or
runMethod (System.out::println, listOfObjectsWithF);
// or even
listOfObjectsWithF.forEach(System.out::println);
If it's not Java8, you may create this interface yourself and realize it for every method:
interface Consumer {
public void apply(ObjectWithF o);
}
public void runMethod(Consumer consumer, ArrayList<ObjectWithF> al) {
for (ObjectWithF o : al) {
consumer.apply(o);
}
}
...
runMethod(new Consumer() {
public void apply(ObjectWithF o) {
//for example
System.out.println (o.toString());
}
}, listOfObjectsWithF);
I have the following scenario where
both testOne() and testTwo calls same callMe() method.
How do I decide inside callMe() method who called callMe().
public void testOne(){
callMe();
}
public void testTwo(){
callMe();
}
public void callMe(){
System.out.println("I was called by following method."+methodName);
}
Any sort of help is appreciated.
Any solution that has you generating a stacktrace and looking at the second frame is one that is going to lead to pain - what you are essentially doing is bypassing the idea of passing what a function needs to it in order for the function to do it's work.
If you need the name of the caller method, then just pass it as a parameter. If you need some other piece of data to decide what to do in the callMe() method, pass it (as a boolean, int, etc.).
It will confuse other developers working on your code why callMe() has what are essentially secret parameters.
public void testOne(){
callMe("testOne");
}
public void testTwo(){
callMe("testTwo");
}
public void callMe(String methodName){
System.out.println("I was called by following method."+methodName);
}
My best answer is to query the stack trace.
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
String previousMethodName = null;
for (int i = 0; (i < stackTrace.length) && (previousMethodName == null); i++)
{
if (stackTrace[i].getMethodName().equals("callMe") && (i < stackTrace.length - 1))
{
previousMethodName = stackTrace[i + 1].getMethodName();
}
}
if (previousMethodName != null)
{
System.out.println("Previous method = " + previousMethodName);
}
sorry, i meant to answer your question and not comment :( so here it is
i think this already answered question may help you out: Get current stack trace in Java
The simplest approach is to use a parameter
public static void testOne(){
callMe("testOne");
}
public static void testTwo(){
callMe("testTwo");
}
public static void callMe(){
System.out.println("I was called by following method."+methodName);
}
However, you can use the call stack.
public static void callMe(){
String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();
System.out.println("I was called by following method."+methodName);
}
I have a class contains 10 methods which are doing almost the same things apart from one key event. Two examples are given below:
Public String ATypeOperation(String pin, String amount){
doSomething();
doMoreStuff();
requestBuilder.buildATypeRequest(pin, amount);
doAfterStuff();
}
Public String BTypeOperation(String name, String sex, String age){
doSomething();
doMoreStuff();
requestBuilder.buildBTypeRequest(name, sex, age);
doAfterStuff();
}
As you can see from the above methods, they are similar apart from calling different methods provided by requestBuilder. The rest 8 are similar too. There is a lot duplicated code here. I feel there is a better way to implement this, but don’t know how. Any ideas and suggestions are appreciated.
Thanks,
Sarah
Use something like RequestBuilder, that accepts all these kinds of parameters:
public RequestBuilder {
// setters and getters for all properties
public Request build() {
doStuff();
Request request = new Request(this);
doAfterStuff();
return request;
}
}
and then
new RequestBuilder().setAge(age).setName(name).build();
What’s the nearest substitute for a function pointer in Java?
Function Pointers in Java
interface RequestBuilder {
void doStuff(params);
}
public RequestBuilder getARequestBuilder() {
return new RequestBuilder() {
void doStuff(params) {
// impl.details
}
}
}
public RequestBuilder getBRequestBuilder() {
return new RequestBuilder() {
void doStuff(params) {
// impl.details
}
}
}
public String buildRequest(yourParams, RequestBuilder builder){
doBefore();
builder.doStuff(yourParams);
doAfter();
}
I think this is called the Strategy pattern. It looks a lot like the Command pattern but because you encapsulate an algorithm it seems to be Strategy :)
What Bozho suggest is the Builder pattern.
I recommend you browse through a list of patterns some time, or buy Head First Patterns. Really fun reading.
You could pass the builder object to a generic buildRequest method. Since not only the algorithm but also the arguments vary, i put them into the builder. I dont think thats a nice solution but i wanted to show a command pattern here :D (Extraneon showed how to decouple params and command)
// call somewhere in the code:
Builder b = new BTypeBuilder();
b.age = "20"; b.sex = "female"; b.name = "eve";
String res = buildRequest(b);
Public String buildRequest(Builder builder)
{
doSomething();
doMoreStuff();
builder.build();
doAfterStuff();
}
// Command pattern
class BTypeBuilder implements Builder
{
String name, age, sex;
// Constructor here
void build()
{
// Do your stuff here
}
}
class ATypeBuilder implements Builder
{
String pin, amount;
// Constructor here
void build()
{
// Do your stuff here
}
}
public interface Builder
{
void build();
}
In addition to other answers, this might also be useful for you (If you want to just plugin your method, not using your parameters for 'before' and 'after' methods)
interface Function0<R> {
R apply();
}
public void performOperation(Function0<Void> operation) {
doSomething();
doBeforeStuff();
operation.apply();
doAfterStuff();
}
then you could use it like this,
final RequestBuilder builder = new RequestBuilder();
performOperation(new Function0<Void>() {
public Void apply() {
builder.buildATypeRequest("1234", "2445");
return null;
}
});
performOperation(new Function0<Void>() {
public Void apply() {
builder.buildBTypeRequest("1234", "2445", "1234");
return null;
}
});
Instead of sending a long parameter list just push all the parameters in a map and send that map as argument.