0

I gotta make an array of method in Java because I have to call methods in a loop and the method called depends to the value of a figure (for example if figure is equal to 8, it's assert8(), etc...) I can do it in a simple if else if statement but it's not going to be clean.

So i wrote this :

boolean assertionsArray[] = {assert0(), assert1(), assert2(), assert3(), assert4(),
                             assert5(), assert6(), assert7(), assert8(), assert9()};

and now I'm searching to make that if my figure is 2, I call assertionsArray[2] etc...

Thank you !

1
  • That's not an array of methods, but an array of boolean. Methods are not like function pointers in C. With Java8, however, it's possible to achieve what you want. Commented Feb 27, 2015 at 14:45

6 Answers 6

1

What you've got is not an array of methods, it is an array of booleans. Each method is called at the moment the array is created, and the return values of these ten methods become values in the array.

If you would like to make an array of something that you can call, make an array of interface implementations that have a method returning boolean. The way you do this depends on the version of Java. Prior to Java 8, you would do it like this:

interface Predicate {
    boolean test();
}
Predicate[] assertionsArray = new Predicate[] {
    new Predicate() {public boolean test() {return assert0(); }}
,   new Predicate() {public boolean test() {return assert1(); }}
,   new Predicate() {public boolean test() {return assert2(); }}
...
,   new Predicate() {public boolean test() {return assert9(); }}
};

Now you can call the assertions like this:

if (assertionsArray[figureIndex].test()) {
    ...
}

Starting with Java 8 you can use the predicate interface included with Java, and use lambdas instead of anonymous implementations:

Predicate<Object>[] assertionsArray = new Predicate<Object>[] {
    o -> assert0(), o -> assert1(), o -> assert2(), o -> assert3(), 
,   o -> assert4(), ...
};
...
if (assertionsArray[figureIndex].test(null)) {
    ...
}
Sign up to request clarification or add additional context in comments.

Comments

0

If you do this:

assert0();

You will call that method and the return value of that method comes into boolean array, which is not what you want. When you want to call a method in an array, you are looking at the reflection package, however this is very, very bad practise to do. I am not going to provide sample code of that as that is not helping you.

As @Dragan pointed out, you are much better of using a switch statement, such as:

switch( figureNumber ) {
   case 0: assert0(); break;
   case 1: ... ; // etc
}

1 Comment

Thanks for all your responses, I'm gonna make a switch statement because it seems to be the most easy method.
0

Putting aside that you cannot do that in java versions lower than 8, you'll be much better off calling a single method that can handle various input.

You provided sparse code, so I'm going to take a shot in the dark here and suggest a switch statement perharps.

Comments

0

What you are doing here will result in an array of boolean, with the results from all your assertX() methods, at the time of array creation.

What you are trying to do here reminds me of function pointers in C, which AFAIK is not possible in Java.

Consider this alternative;

Have one method called: assertByIntArgument(int n) which calls the appropriate assertX() method, based on the argument n

Something like this:

private boolean assertByInt(int n){
  switch(n){
    case 1: return assert1(); break;
    case 2: return assert2(); break;
    // ...
  }
}

2 Comments

@Magnamag not familiar with Java 8, hence the remark "AFAIK". Thanks for pointing it out that it's possible tho. Feel free to edit and show how it can be done in Java 8. :)
Sorry, I didn't mean to be so harsh :) I read quickly and 'skipped' the AFAIK.
0

With Java 8, you could have the following:

Supplier<Boolean> assertionsArray = {
    SomeClass::assert0(), 
    SomeOtherClass::assert1(), 
    SomeClass::assert2(), 
    SomeClass::assert3(), 
    SomeClass::assert4(),
    SomeClass::assert5(), 
    SomeClass::assert6(), 
    SomeClass::assert7(), 
    SomeClass::assert8(), 
    this::assert9()
};

Then, in a loop or somewhere else:

boolean result = assertionsArray[i].get();

Comments

0

This answer is more of a 'as a matter of interest' than a real solution. The best solution in non-Java 8 environment is probably a switch. Another lead would have been reflection, as presented below, but please be aware that:

  • it is less efficient and performant;
  • it leaves your IDE (and compiler) blind and hinders you when navigating your code;
  • too much reflection makes code just impossible to read.

Use at your own risk.


If you want to stick to several methods though, you could use reflection.

If your methods are declared in MyClass, invoking a no-arg method would be the following:

MyClass.class.getDeclaredMethod("assert" + i).invoke();

If you need to pass arguments (let's say an int and a String), update to the following:

MyClass.class.getDeclaredMethod("assert" + i, int.class, String.class).invoke(3, "Hello");

4 Comments

Thats very bad practise as you can work around this. Avoid using reflection like this
I precised this was not the correct solution, and I agree this is not ideal, but it can be of help to someone blocked otherwise. I am aware it prevents many optimizations, but I am interested to know why it is very bad practice. Would you care to elaborate and enlighten me?
OK, I knew all that. Thank you for the info. The switch is probably the best solution (in a not-Java 8 environment at least). I'll update my answer to make it more obvious.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.