2014-02-06 4 views
0

У меня очень простой вопрос, но, похоже, никто не ответил на него раньше.Кастинг общих типов в Java (например, значение T = (T) inputParam)

Мне нужно сделать отливку с объекта на общий тип T. что-то вроде этого.

T value = (T) param;

Вот мой пример кода.

public class App { 
    public static void main(String[] args) { 
     MyGeneric<Double> myGeneric = new MyGeneric(); 
     Object obj = myGeneric.getValue("12.45"); 
    } 
} 

public class MyGeneric<T> { 
    public T getValue(Object value) { 
     return (T) value; 
    } 
} 

У меня есть общий класс типа, и способ, который принимает объект в качестве параметра и возвращает один и тот же объект оттенок.

Я ожидаю, что мой класс автоматически отбрасывается с «12.45» до двойного значения 12.45. Однако мой класс просто ничего не делает. В конце значение в переменной «obj» по-прежнему является строкой.

Мой вопрос: как достичь того, чего я хочу. Причина, по которой я отправляю строку «12.45» в мой метод getValue(), состоит в том, что эти данные не контролируются мной. Внешнему приложению необходимо использовать мой общий класс, и по какой-то причине они отправляют строковое представление значения «12.45». Таким образом, мой класс может обрабатывать целые числа, float, double или что-то еще.

+0

Вы просто хотите обрабатывать числовые значения? –

ответ

5

Дело в том, что приведение не может фактически изменить тип объекта. Он может ссылаться на объект любым из типов, к которым он уже принадлежит, но он не может изменить фактический тип.

A String не является Double, поэтому вы не можете отличить String в Double. Вам нужно позвонить Double.valueOf().

+0

Спасибо за ваш ответ, я изменю свой метод, чтобы вместо этого использовать valueOf. – user3279112

4

Вы не можете литой a String до Double; вам нужно преобразовать значение. Кастинг означает, что JVM указывает, что объект, известный как один супертип, действительно является объектом подтипа, и здесь это не так.

Вместо этого ваш код, который знает значение, является String и хочет, чтобы он был Double должен использовать `Double.valueOf (stringVariable).

+0

Спасибо за ваш ответ, я понял. Поэтому, если мне приходится иметь дело с различными типами входов, то есть Integer, Float, Double и т. Д., Мне нужно создать другой метод для каждого возможного значения. – user3279112

+0

@ user3279112 Независимо от того, какой код принимает вход, он должен будет преобразовать его из потока символов в соответствующий тип, основываясь на некоторой стратегии, которую вы программируете в ней (например, вызывая 'valueOf', используя« Сканер »и т. Д.). – chrylis

0

Просто схематичны, но вы можете использовать (1) требуемый класс, (2) отражение

public static <T> T getValue(Class<T> klazz, Object value) { 
    try { 
     // Try whether value has correct type: 
     return klazz.cast(value); 
    } catch (ClassCastException e) { 
     // Try whether klazz has static .valueOf(String) 

     // Then value not null: 
     String s = value.toString(); 
     Method valueOf = klazz.getDeclaredMethod("valueOf", String.class); 
     int modifiers = valueOf.getModifiers(); 
     if (Modifiers.isStatic(modifiers)) { 
      valueOf.setAccessible(true); 
      return valueOf.invoke(null, s); 
     } 
    } 
    throw new IllegalArgumentException(value); 
} 

double x = getValue(Double.class, "12.34"); 
+0

Если вы собираетесь решить эту проблему, вы можете использовать что-то вроде преобразователей типа Spring. – chrylis

Смежные вопросы