1

I use Jexl lib from apache and have some problems with using the evaluate() method of Expression class. Here is the code of NelderMead class:

import org.apache.commons.jexl2.*;

public class NelderMead {
    // контсанты
    private static int      M = 3;
    private static double   E = 0.005;
    private static double   A = 1.000;
    private static double   B = 0.500;
    private static double   Y = 2.000;

    // переменные
    private JexlEngine jexl;
    private Expression func;
    private String funcString = "";
    private MapContext[] iterations;

    public NelderMead(){
        this.jexl = new JexlEngine();
    }

    public NelderMead(String funcString){
        this.jexl = new JexlEngine();
        this.setFunc(funcString);
    }


    public void setFunc(String funcString){
        this.funcString = funcString;
        this.func = this.jexl.createExpression(funcString);
    }

    public double funcEval(MapContext args){
    return ((Double) this.func.evaluate(args)).doubleValue();

    }

    public boolean checkCriterian(){
        return true;
    }
}

And the code of testcase is:

import org.apache.commons.jexl2.MapContext;


public class Test {

    /**
     * @param args
     */
    public static void main(String[] args) {
        NelderMead nm = new NelderMead("(x1-2)^4+(x1-2*x2)^2");
        MapContext mc = new MapContext();
        mc.set("x1", 2);
        mc.set("x2", 1);
        System.out.println(nm.funcEval(mc));

    }

}

And when I run the testcase, it cause the following error:

Exception in thread "main" java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.Double
    at NelderMead.funcEval(NelderMead.java:33)
    at Test.main(Test.java:14)

I can't understand why it can't cast to Double?

PS

Here is the javadoc of evaluate() function.

Dmitry Belaventsev
  • 6,347
  • 12
  • 52
  • 75

2 Answers2

1

this test case should mimic your problem

package com.sg2net.test;

public class TestCast {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        TestCast tc= new TestCast();
        tc.funcEval();
    }

    public double funcEval(){
        return ((Long) eval()).doubleValue();
    }   

    private Object eval() {
        return new Long(1);
    }

}

It runs without problems. Is the code you posted the code that gives you the exception?

here is you code with the Long modification

import org.apache.commons.jexl2.*;

public class NelderMead {
    // контсанты
    private static int      M = 3;
    private static double   E = 0.005;
    private static double   A = 1.000;
    private static double   B = 0.500;
    private static double   Y = 2.000;

    // переменные
    private JexlEngine jexl;
    private Expression func;
    private String funcString = "";
    private MapContext[] iterations;

    public NelderMead(){
        this.jexl = new JexlEngine();
    }

    public NelderMead(String funcString){
        this.jexl = new JexlEngine();
        this.setFunc(funcString);
    }


    public void setFunc(String funcString){
        this.funcString = funcString;
        this.func = this.jexl.createExpression(funcString);
    }

    public double funcEval(MapContext args){
    return ((Long) this.func.evaluate(args)).doubleValue();

    }

    public boolean checkCriterian(){
        return true;
    }
}

It runs with no problems. The evaluate functions returns a Long which is an Object. The evaluate function can return any class since Object is the root class in Java.

Giovanni
  • 3,951
  • 2
  • 24
  • 30
  • I update the code in answer. And maybe it will be helpful - evaluate() function have Object as return type. – Dmitry Belaventsev Nov 26 '11 at 13:24
  • My method eval has Object as return type. Your code still seems the same – Giovanni Nov 26 '11 at 13:31
  • Now I see the new code, your expression returns a Long object, it cannost be cast to Double sine they are Object not primitive types. You have user a Long variable for holdin the this.func.evaluate result and the convert it to double – Giovanni Nov 26 '11 at 13:35
  • I have "public double funcEval(MapContext args){" head of function, so it returns double. I have "return ((Double) this.func.evaluate(args)).doubleValue();" return statement. So here is cast history Object->Double->double. So, I don't see Long here... – Dmitry Belaventsev Nov 26 '11 at 13:46
  • Long is the object returned by this.func.evaluate(args) and it cannot be cast to Double. Can you try to use return ((Long) this.func.evaluate(args)).doubleValue(); – Giovanni Nov 26 '11 at 13:53
  • I tried to use your variant of cast - but no sense. And I steel don't unserstand - where you find Long type? In link (in the PS section of my question) it's clear that returned type is Object. Or I missunderstand smth.? – Dmitry Belaventsev Nov 26 '11 at 13:57
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/5374/discussion-between-giovanni-and-dizpers) – Giovanni Nov 26 '11 at 14:02
  • yeah! you are right - it works! thx a lot! PS I tried this modification before - but it fired an error in past - but it's no errors now!:) thx!:)) – Dmitry Belaventsev Nov 26 '11 at 15:29
0

return type of method is double why you are casting the result in return statement to Long ?

jmj
  • 237,923
  • 42
  • 401
  • 438