1

在 BeanShell 中变量可以是nullvoidvoid有没有办法使用在 BeanShell 和 Java 中都可以工作(未修改,即复制/粘贴)的代码来测试两者(或至少)?类似的东西:SomeUtilityClass.isNullOrVoid(...)

我使用复杂的 BeanShell 脚本,并且能够将代码从 Java IDE 复制/粘贴到脚本中,这对我的工作效率和代码质量有很大帮助(是的,这意味着我没有使用 BSH 的脚本功能)。唯一的问题是测试void迫使我事后手动调整每个脚本。

问题void

  • 检查null未捕获void

String foo; System.out.println("is null: "+ (foo == null));

prints is null: false,这会导致类似if (var != void && var != null) { ... }which 在 Java 中不起作用的代码(并且声明void为常量是不可能的,因为它是保留字)

  • bsh.NameSpace没有检查voidgetVariable(...)返回的方法void

String foo; System.out.println("variable: "+ this.namespace.getVariable("foo"));

打印variable: void,所以我们回到第一方。即使有一种方法可以做到这一点(假设我将使用适当的方法编写一个自定义 NameSpace 子类,并且setNameSpace(...)它)也需要一种以跨环境方式调用它的方法(请参阅下一点)。

  • 用 like 方法编写自定义帮助器类isNull(Object bshNameSpace, String varName, Object var)似乎是不可能的。

像这样的辅助方法:

public class Helper {
  public static boolean isNullOrVoid(This bshThis, String name) throws Exception {
    Primitive p = (Primitive) bshThis.getNameSpace().getVariable(name);
    return p == Primitive.NULL || p == Primitive.VOID;
  }
}

从 BeanShell 工作得很好,但没有办法(我知道)将它重新设计为在 Java 中工作(使用反射或其他方式),因为它需要使用方法变量而不是实例字段。另一种(笨重)版本:

  public static boolean isNullOrVoid(Object bshThis, String name, Object var) throws Exception {
    if (!(bshThis instanceof This)) {
      return var == null;
    }
    Primitive p = (Primitive) ((This)bshThis).getNameSpace().getVariable(name);
    return p == Primitive.NULL || p == Primitive.VOID;
  }

如果第三个参数是Undefined argument ,则适用于 Java 但不适用于 BeanShell 。

  • 声明自定义 BSH 命令也不是一种选择。

即使在脚本本身中定义了辅助方法,它也会以完全相同的方式爆炸,并带有未定义的参数异常:

public boolean isNullOrVoid(Object var) {
    return var == null || var == void;
}
String foo;
System.out.println(isNullOrVoid(foo));
4

1 回答 1

3

我无法发表评论,因为我在这里相对较新。我对此深表歉意,因为我更愿意将以下内容作为评论。

我确实质疑你正在尝试做的事情的前提。BeanShell 是弱类型的,这就是你需要 void 的原因。我可以说print(x);,在这个脚本中 x 是无效的。Java 是强类型的,并且此代码无法编译(显然,假设所有类/方法代码都已到位)。这意味着如果您将纯 Java 代码粘贴到 BeanShell 中,那么您永远不会遇到对 void 的需求。

但是如果你坚持,你可以尝试用 eval() 命令来愚弄。共享方法如下所示:

boolean isNullOrVoid(Object o) {
 return eval("o == void") || o == null;
}

这对 BeanShell 来说很好,但是现在您必须在 Java 代码中实现 eval() 命令,但是因为(如前所述)没有 void 的概念,所以它应该总是返回 false。

PS 无效检查应该在无效检查之前。

于 2013-01-07T02:05:28.207 回答