开发者

Dynamic if statement evaluation problem with string comparison

I tried the example given in this thread to create if statement dynamically using BeanShell. But it is not working fine. Instead of using "age" variable as integer, i have used string in the below exa开发者_StackOverflow社区mple. I am getting "fail" as answer instead of "success".

Can anyone help me?

/*
To change this template, choose Tools | Templates
and open the template in the editor.
*/

import java.lang.reflect.*;
import bsh.Interpreter;

public class Main {
  public static String d;

  public static void main(String args[])
  {
    try {
      String age = "30";

      String cond = "age==30";


      Interpreter i = new Interpreter();

      i.set("age", age);

      System.out.println(" sss" + i.get("age"));

      if((Boolean)i.eval(cond)) {
        System.out.println("success");
      } else {
        System.out.println("fail");
      }
    }
    catch (Throwable e) {
      System.err.println(e);
    }
  }
}

Thanks, Mani


You have to choose either numeric comparison or String comparison. This requires using a compatible condition and type for age.

Numeric:

  int age = 30;
  String cond = "age==30";

String:

  String age = "30";
  String cond = "age.equals(\"30\")";


When you compare two objects with the == operator, you're comparing two references. You're essentially asking whether two different names refer to the same object in memory.

To compare the actual values of objects, you need to use the equals() method. This is something that's very important to understand about Java.


@Matthew Flaschen is correct. As an aside, you can simplify your output as follows:

System.out.println(cond + " is " + i.eval(cond));

which produces

age == 30 is true


You are using == to compare string types. Try using age.equals("30") instead.

EDIT: to show it working

If you use this as the definition of cond:

String cond = "age.equals(\"30\")";

Output:

 sss30
success

In response to the question about using =="30" instead, here is the answer to that:

If your String age is interned, because it is a compile-time constant for example, then it could be true.

final String age = "30";

However if you explicitly new the String or it is otherwise not interned, then it will be false.

String age = new String("30");

You can run both examples to see this in effect. Possibly - you may get fail for both.

Now, just because interning exists doesn't mean one should ever rely on it for comparing String types. The == operator should only be used to compare primitives to each other, and to compare reference types to see if they point to the same object, so for reference types we could say it is seeing if two objects are identical instead of equal.

Sometimes through the magic of the JVM and JDK, String and other primitive wrappers like Integer may be comparable with ==, but the situations for this are limited and not reliable.


The string compare with "==" in the bsh interpreter is not working like expected.

It is working like that: (copied from the link bellow)

    Beanshell handles '==' like java and not e.g. like JavaScript. That means you've got to use "equals" to compare instances.
    bsh % "abc" == "abc"; => true
    bsh % "abc" == new String("abc"); => false
    bsh % "abc".equals("abc"); => true
    bsh % "abc".equals(new String("abc")); => true

further information here: https://code.google.com/p/beanshell2/issues/detail?id=86

So you have to use the ".equal()", or compile your own bsh version, like i did it. (read the complete issue above)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜