Java, как проверить, является ли строковое значение типом данного класса <?>
Хорошо, это довольно сложный вопрос, и я полностью потерялся.
Предположим, что у вас есть строка и общий класс. Вот так.
String string;
Class<?> clazz;
Как бы вы проверили, соответствует ли String значение, которое класс мог бы равным.
Например, скажем, что:
String string = "true";
Class<?> clazz = Boolean.class;
Как я могу проверить и увидеть, что строка "true" на самом деле является логической?
Вот еще один пример. Допустим, что:
String string = "true";
Class<?> clazz = Integer.class;
Как проверить и увидеть, что строка "true" не является целым?
Ответы
Ответ 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)
завершится с ошибкой.