Межъязыковой Java/Beanshell способ проверки на пустоту и нуль

В BeanShell переменные могут быть null или void. Есть ли способ проверить оба (или, по крайней мере, void) с помощью кода, который будет работать (неизмененный, т.е. скопированный/вставленный) как в BeanShell, так и в Java? Что-то вроде: SomeUtilityClass.isNullOrVoid(...).

Я работаю со сложными сценариями BeanShell, и возможность копировать/вставлять код из Java IDE в сценарий очень помогает моей производительности и качеству кода (да, это означает, что я не использую функции сценариев BSH). Единственная проблема заключается в тестировании для void, что вынуждает меня впоследствии вручную настраивать каждый скрипт.

Проблемы с void:

  • Чек на null не ловит void:

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

печатает is null: false, что приводит к коду, подобному if (var != void && var != null) { ... }, который не работает в Java (и объявление void константой невозможно, так как это зарезервированное слово)

  • bsh.NameSpace не имеет метода проверки void, а getVariable(...) возвращает void:

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

печатает variable: void, так что мы вернулись к исходной точке. Даже если бы существовал метод для этого (скажем, я бы написал собственный подкласс NameSpace с соответствующим методом и setNameSpace(...) его), должен быть способ вызвать его в кросс-среде (см. следующий пункт).

  • написание собственного вспомогательного класса с методом типа 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;
  }

работает из Java, но не из BeanShell, если третьим параметром является Неопределенный аргумент.

  • объявление пользовательской команды BSH также не является вариантом.

Даже если вспомогательный метод определен в самом скрипте, он взрывается точно так же с исключением Неопределенный аргумент:

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

person Gilead    schedule 09.10.2012    source источник
comment
Какую именно версию Beanshell вы используете, потому что я пробовал ваши примеры кода и не вижу, чтобы что-то возвращалось пустым. Черт возьми, void — это даже не тип в Java. Каким-то образом имело бы смысл возвращать Void, но это тоже не так.   -  person Edwin Dalorzo    schedule 16.11.2012


Ответы (1)


Я не могу комментировать, так как я здесь относительно недавно. Я прошу прощения за это, так как я предпочел бы заявить следующее в качестве комментария.

Я сомневаюсь в предпосылке того, что вы пытаетесь сделать. BeanShell имеет слабый тип, поэтому вам нужен void. Я мог бы сказать print(x);, и в этом скрипте x недействительно. Java является строго типизированным, и этот код не будет компилироваться (при условии, что весь код класса/метода, очевидно, на месте). Это означает, что если вы вставляете чистый Java-код в BeanShell, вам никогда не придется сталкиваться с необходимостью в void.

Но если вы настаиваете, вы можете попробовать пошалить с помощью команды eval(). Общий метод будет выглядеть так:

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

Это нормально для BeanShell, но теперь вам нужно реализовать команду eval() в коде Java, но поскольку (как упоминалось ранее) не существует понятия пустоты, она всегда должна возвращать false.

PS недействительная проверка должна предшествовать нулевой проверке.

person GaryMcM    schedule 07.01.2013