0

I'm trying to make a function that takes a String and a double as parameters in Java, like this:

public static double calc(String fx, double arg) {
    return fx.convertToFunction(arg);   // Pseudocode

}

For instance, to calculate the cosine of a number (PI, for example), the code would be:

calc("cos", Math.PI);

and the function calc has to convert "cos" into Math.cos().

Is that at least possible?

Laura
  • 2,857
  • 3
  • 25
  • 43
bury_5
  • 65
  • 7

7 Answers7

4

What you are looking for is called Reflection in Java.

Have a look at this topic: How do I invoke a Java method when given the method name as a string?

Without the required checks for Exceptions your code may look something like this:

//assume that you have an Object that you want to invoke the method on
MyObject obj = new MyObject();
//the variable `method` will hold your function
java.lang.reflect.Method method;
//paremters can be provided to identify a specific method among overloaded methods
method = obj.getClass().getMethod(methodName, param1.class, param2.class, ..);
//invoke the method of your object
method.invoke(obj, arg1, arg2,...);
Community
  • 1
  • 1
Dennis
  • 480
  • 5
  • 16
2

An easiest approach to what you want to do is..

You can easily do it using if else or switch

   calc("cos", Math.PI);

in the function check it as

 if(stringValue.equals("cos")){
  call the cos function
 }
Danyal Sandeelo
  • 11,068
  • 6
  • 37
  • 64
0

No, you can use a design pattern or implement with switch:

switch (command) {
case "cos" : return Math.cos(dblParam);
}
ACV
  • 8,090
  • 4
  • 56
  • 72
0

Really not in an easy way. You can define a Map to relate a name with a method (or better, a functional interface), or use reflection.

For example (using a functional interface, Java 7 syntax):

// Define functions
final Runnable cosFunction = new Runnable() {    
    @Override
    public void run() {
        // Do cosine
    }
}

// Store functions
Map<String, Runnable> functionMap = new HashMap<>();
functionMap.put("cos", cosFunction);

// Retrive functions
final Runnable function = functionMap.get("cos");
function.run();

Note that using Runnable doesn't allow you to return a value.

In functional programming this is way easier, I suggest you look into Clojure or Scala, which are JVM-based.

m0skit0
  • 23,052
  • 11
  • 71
  • 113
0

I suggest you reconsider whether this is a good idea, however you can do this.

public static double calc(String fx, double arg) {
    try {
        Method math = Math.class.getMethod(fx, double.class);
        return (Double) math.invoke(null, arg);
    } catch (Exception e) {
        throw new IllegalArguementException(e);
    }
}
Peter Lawrey
  • 498,481
  • 72
  • 700
  • 1,075
0

You need to use reflection api as below:

String methodName = "cos";
double arg = Math.PI;

try {
    Method method = Math.class.getDeclaredMethod(methodName,
            double.class);//get cos method from math class that accepts double as parameter
    method.setAccessible(true);//i trust this call
    double time = (Double) method.invoke(null, arg);//invoke the method with PI
    System.out.println(time);
} catch (Exception e) {//handle all exceptions or individual according to business need
    e.printStackTrace();
}
SMA
  • 33,915
  • 6
  • 43
  • 65
0

Java provides a facility called reflection. This provides methods to access methods, variables etc. by name. Most of these facilities are on the java.lang.Class object.

  • Class.getMethod(name, args) on java.lang.Math to get a java.reflect.Method reference
  • Call the method reference with method.invoke(null, args). The null here is the instance, which doesn't make sense for static methods

Code

public static void main(String[] args) throws Exception {
    System.out.println(calc("cos", Math.PI));
    System.out.println(calc("sin", Math.PI /2));
}

public static double calc(String fx, double arg) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
    return (Double) Math.class.getMethod(fx, double.class).invoke(null, arg);
}
Adam
  • 32,907
  • 8
  • 89
  • 126