Приведение объектов к Integer,string,

У меня есть одна маленькая проблема. У меня есть список типов (int, string,..)

ArrayList<Class> typeList;

и у меня есть некоторые входные значения;

ArrayList<Object> values;

Как привести какое-то значение к какому-то типу, если я знаю, какой тип из typeList является значением;

typeList.get(i).cast(values.get(i)); ‹- это не работает???

На самом деле я генерирую динамическую форму во время выполнения. С отражением Java я получаю типы параметров из методов из некоторого класса, я создаю форму с полями ввода, а затем я хочу преобразовать текст из полей ввода в определенные типы из типов параметров, которые я получил с отражением Java из некоторого класса.


person Milan    schedule 13.04.2010    source источник
comment
Почему вы хотите это сделать? Чего вы на самом деле пытаетесь достичь?   -  person Michael Borgwardt    schedule 13.04.2010
comment
во время выполнения я генерирую динамическую форму с полями ввода. и мне нужно преобразовать текст из полей ввода в строку, int или какой-то другой сложный класс.   -  person Milan    schedule 13.04.2010
comment
Также расскажите о том, чего вы собираетесь достичь после приведения типов? Собираетесь ли вы вызывать некоторые методы (библиотека/ваши собственные?)   -  person Kannan Ekanath    schedule 13.04.2010


Ответы (4)


В большинстве случаев вы просто не можете привести объект одного типа к другому типу. В тех случаях, когда вы можете выполнить приведение, будет работать следующее:

Class<SomeClass> clazz = ...
SomeOtherClass obj = ...
SomeClass result = clazz.cast(obj);

Обратите внимание, что SomeClass — это тип, который вы приводите к к, а не к типу, к которому вы приводите из.

Однако, если значение obj имеет неправильный тип (т. е. SomeClass или какой-либо подтип SomeClass), приведенное выше даст вам ClassCastException.

Похоже, ваша программа должна пытаться преобразовать объекты, а не просто приводить их. Или, если вам действительно нужно привести объекты, ваша программа должна быть готова к работе с возможными ClassCastException.

person Stephen C    schedule 13.04.2010

Если у вас не так много типов сейчас или в будущем, я бы посоветовал использовать структуру if-else, предложенную Calm Storm.

Однако, если вы хотите сделать систему более универсальной и расширяемой, вы можете использовать что-то похожее на механизмы JavaBeans, т.е. иметь «редактор» для каждого типа:

interface TypeEditor {
    public String generateCode(Object value);
}

Затем используйте разные конкретные классы для разных типов, например StringEditor, IntegerEditor...

Для работы с редакторами создайте что-то вроде TypeEditorManager:

public class TypeEditorManager {
    private static Map<Class, TypeEditor> editors = ....;
    static {
        editors.put(String.class, new StringEditor());
        editors.put(Integer.class, new IntegerEditor());
        ...
    }

    public TypeEditor getTypeEditor(Object value) {
        return editors.get(value.getClass());
    }
}

Обратите внимание, что getTypeEditor вернет значение null, если класс значения является подтипом зарегистрированного класса. Я оставляю это вам в качестве домашнего задания, чтобы выяснить, как сопоставлять суперклассы ;-) (Хорошо, я ленив...)

Вы также можете упростить расширение, сопоставив типы с редакторами, например, в отдельном файле, конфигурации Spring и т. д.

А затем сделайте это еще лучше, используя дженерики.

person fish    schedule 13.04.2010
comment
О, но это не то, чего вы хотели добиться, извините :-( Я все равно оставлю это здесь на случай, если это может принести вам какую-то пользу. - person fish; 13.04.2010

РЕШЕНИЕ:

Итак, я решаю проблему следующим образом:

if(typeList.get(t).equals(byte.class))
{
inputParams[t] = Byte.parseByte(input.getValue().toString());
}   
else if(typeList.get(t).equals(short.class))
{
inputParams[t] = Short.parseShort(input.getValue().toString());
}
else if(typeList.get(t).equals(int.class))
{
inputParams[t] = Integer.parseInt(input.getValue().toString());
}           
else if(typeList.get(t).equals(long.class))
{
inputParams[t] = Long.parseLong(input.getValue().toString());
}           
else if(typeList.get(t).equals(float.class))
{
inputParams[t] = Float.parseFloat(input.getValue().toString());
}           
else if(listOperationParameters.get(t).equals(double.class))
{
inputParams[t] = Double.parseDouble(input.getValue().toString());
}           
else if(typeList.get(t).equals(boolean.class))
{
inputParams[t] = Boolean.parseBoolean(input.getValue().toString());
}           
else if(typeList.get(t).equals(char.class))
{
inputParams[t] = input.getValue().toString().charAt(0);
}           
else{
inputParams[t] = typeList[t].cast(input.getValue());
}

Примитивные типы нельзя приводить, поэтому я проверяю, и в конце, если это какой-то другой объект (также String), я привожу его.

Спасибо всем за помощь!

person Milan    schedule 14.04.2010

Учитывая ваше обновление в разделе комментариев, вы можете попробовать следующее, предполагая, что список классов известен (код, который не компилируется/запускается, но просто предоставлен для руководства)

for(int i = 0 ; i < valueList.size(); i++) {
    Object object = valueList.get(i);
    if(object instanceof String) {
        //generate code for string
    } else if (object instanceof Number) {
        //generate code for number
    } 
    //do like this for all class types
}
person Kannan Ekanath    schedule 13.04.2010
comment
а если у меня какой-то конкретный класс? Какой-то другой класс. - person Milan; 13.04.2010
comment
На самом деле вам вообще не нужен typeList в этом случае, просто сравните 'object instanceof String' вместо 'clazz instanceof String... и на самом деле 'clazz instanceof String' даже не работает, вы должны сделать clazz.isAssignableFrom(String .class), если вы хотите это сделать. - person fish; 13.04.2010
comment
Как я уже сказал, вам нужно иметь действительный конкретный список классов. С другой стороны, вы можете получить список значений, которые реализуют интерфейс и генерируют код из интерфейса. - person Kannan Ekanath; 14.04.2010