Подтвердить что ты не робот

Java, как проверить, является ли строковое значение типом данного класса <?>

Хорошо, это довольно сложный вопрос, и я полностью потерялся.

Предположим, что у вас есть строка и общий класс. Вот так.

String string;
Class<?> clazz;

Как бы вы проверили, соответствует ли String значение, которое класс мог бы равным.

Например, скажем, что:

String string = "true";
Class<?> clazz = Boolean.class;

Как я могу проверить и увидеть, что строка "true" на самом деле является логической?

Вот еще один пример. Допустим, что:

String string = "true";
Class<?> clazz = Integer.class;

Как проверить и увидеть, что строка "true" не является целым?

4b9b3361

Ответ 1

Учитывая, что вы хотите использовать это только для типов Wrapper, вы можете использовать некоторый рефлексивный хак здесь (обработка исключений для нерелевантного кода здесь проигнорирована для краткости):

String string = "ABC";
Class<?> clazz = Integer.class;

Method method = clazz.getDeclaredMethod("valueOf", String.class);

if (method != null) {
    try {
        Object obj = method.invoke(null, string);       
        System.out.println("Success : " + obj);

    } catch (InvocationTargetException ex) {
        System.out.println("Failure : " + string + " is not of type " + 
                                          clazz.getName());
    }
}

Я принимаю во внимание тот факт, что каждый класс-оболочка имеет статический метод valueOf, который принимает параметр типа String и возвращает значение этого типа wrapper. И генерирует исключение, если параметр не конвертируется в соответствующий тип оболочки.

Итак, в приведенном выше случае, если выбрано исключение, значение String не относится к типу clazz.

P.S.: Обратите внимание, что для Boolean.class любая строка, которая не является "true", будет считаться false.

Ответ 2

Я предполагаю, что вы реализуете какую-то спецификацию/протокол или подобное.

  • Посмотрите на Spec.
  • Определить грамматику допустимого ввода
  • Разберите эту грамматику.

Это похоже на то, что Языки программирования делают с литералами.

Ответ 3

В javascript вы можете eval() строку. На Java у вас нет таких средств. Вам нужно будет выполнить свою эвристику для этой проверки.

Единственное, что вы можете сделать, это попытаться разобрать строку с данным классом. Как:

Iteger.parseInt(stringValue);

Если синтаксический анализ завершается успешно, строка может использоваться как значение для этого типа. Если это не удается, вы получите исключение. Внесите эти проверки и затем выведите некоторые выводы.

Ответ 4

Я не могу проверить это решение прямо сейчас, но почему бы не что-то подобное? Если вы можете сами перечислять все возможные классы, просто создайте в классе некоторые инструкции switch.

boolean isStringClass (Class clazz, String string) {

    try {
        if (Integer.class == clazz) {
           Integer.valueOf(string);
        } else if (Boolean.class = clazz) {
           Boolean.valueOf(string);
        } [...etc]
    } catch (Exception e) {
        return false;
    }

    return true;
}

Конечно, вам нужно будет знать все возможные классы, и вам нужно знать о методе, принадлежащем этому классу, который может разбирать строку и возвращать ее тип. Для примитивных оберток, которые будут valueOf.

Если вы планируете конвертировать только конверты, решение Rohit было бы лучшим выбором. Однако, если вы этого не делаете, и вы не можете добавить метод valueOf к этому новому классу, это может быть вашим единственным вариантом.

Ответ 5

Я бы рассмотрел использование механизма JavaBeans PropertyEditor для этого.

@Test
public void testIsOfType() {        
    assertFalse(test("nope", Integer.class));
    assertFalse(test("nope", Boolean.class));

    assertTrue(test("1", Integer.class));
    assertTrue(test("true", Boolean.class));
}

boolean test(String str, Class<?> clazz) {
    PropertyEditor propertyEditor = PropertyEditorManager.findEditor(clazz);
    if (propertyEditor != null) {
        try {           
            propertyEditor.setAsText(str);
            return true;
        } catch (Exception ex) {}
    }
    return false;
}

Это позволяет избежать необходимости явного отражения, и если вы когда-либо решили, что вам нужно тестировать классы, отличные от примитивных оберток, вы можете зарегистрировать новый редактор с помощью PropertyEditorManager.registerEditor().

К сожалению, проблема с Rohit в том, что test("1", Number.class) завершится с ошибкой.