Перечисления Java в универсальном типе - PullRequest
8 голосов
/ 15 июня 2010

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

Любая помощь приветствуется.

Чего я хочу добиться, так это определить последующееотображает как:

public class XEnumTypeHandler extends CommonEnumTypeHandler<X> {
}

Текущий код:

public class CommonEnumTypeHandler<T extends Enum> implements TypeHandlerCallback {

 public void setParameter(ParameterSetter ps, Object o) throws SQLException {
  if (o.getClass().isAssignableFrom(**T**)) { 
   ps.setString(((**T**) o).value().toUpperCase());
  } else
   throw new SQLException("Excpected ParameterType object than: " + o);
 }

 public Object getResult(ResultGetter rs) throws SQLException {
  Object o = valueOf(rs.getString());
  if (o == null)
   throw new SQLException("Unknown parameter type: " + rs.getString());
  return o;
 }

 public Object valueOf(String s) {
  for (T pt : T.**values()**) {
   if (pt.**value()**.equalsIgnoreCase(s))
    return pt;
  }
  return null;
 }
}

Я добавил метки ошибок в приведенный выше код, сообщения об ошибках в следующем порядке:

  • T не может быть разрешено
  • Значение метода () не определено для типа T
  • Значения метода () не определены для типа T
  • Значения метода () не определен для типа T

Я решил эту проблему с помощью следующего кода:

public class CommonEnumTypeHandler<T extends Enum> implements TypeHandlerCallback {

    Class<T> clazz;

    public CommonEnumTypeHandler(Class<T> clazz) {
        this.clazz = clazz;
    }

    public void setParameter(ParameterSetter ps, Object o) throws SQLException {
        if (o.getClass().isAssignableFrom(clazz)) {
            ps.setString(((T) o).name().toUpperCase());
        } else
            throw new SQLException("Excpected " + clazz + " object than: " + o);
    }

    public Object getResult(ResultGetter rs) throws SQLException {
        Object o = valueOf(rs.getString());
        if (o == null)
            throw new SQLException("Unknown parameter type: " + rs.getString());
        return o;
    }

    public Object valueOf(String s) {
        return Enum.valueOf(clazz, s);
    }
}

Наследование от этого класса я делаю:

public class SalesChannelTypeHandler extends CommonEnumTypeHandler<SalesChannel> {

    public SalesChannelTypeHandler() {
        super(SalesChannel.class);
    }

    public SalesChannelTypeHandler(Class<SalesChannel> clazz) {
        super(clazz);
    }

}

Ответы [ 2 ]

8 голосов
/ 15 июня 2010

Я не уверен, что вы делаете (общий обзор в словах было бы неплохо), но:

  • Вы не можете сделать isAssignableFrom(T) (вам нужен объект Class), и вы также не можете сделать instanceof T (непатентованные шаблоны). Вы можете вместо этого хотеть передать токены Class<T>.
  • Вы смотрели на EnumMap?

Смотри также


До сих пор не ясно, что нужно, но, возможно, это что-то вроде этого:

enum Color { BLACK, WHITE; }

public static void main(String[] args) {
    Color c = Enum.valueOf(Color.class, "black".toUpperCase());
    System.out.println(c); // prints "BLACK"
}

Поэтому мы используем Enum.valueOf, который принимает токен типа Class<T extends Enum<T>>, и запрашиваем его для константы enum с заданным именем. valueOf является НЕ без учета регистра, но согласно соглашениям все константы должны быть в верхнем регистре, поэтому мы просто берем строку запроса и поворачиваем ее .toUpperCase().

4 голосов
/ 15 июня 2010

Как указывает Polygenelubricants, вам нужно передавать конкретные типы времени выполнения, например, Class<?> вместо синтаксических типов времени компиляции, таких как общие параметры.Вот переписать, как вы могли бы использовать его:

public abstract class CommonEnumTypeHandler<E extends Enum<E>> implements TypeHandlerCallback {
    private Class<E> enumClass;

    public CommonEnumTypeHandler(Class<E> enumClass) {
        this.enumClass = enumClass;
    }

    public void setParameter(ParameterSetter ps, Object o) throws SQLException {
        if (enumClass.isInstance(o)) {
            ps.setString((enumClass.cast(o)).name().toUpperCase());
        } else {
            throw new SQLException("Excpected ParameterType object than: " + o);
        }
    }

    public Object getResult(ResultGetter rs) throws SQLException {
        try {
            return Enum.valueOf(enumClass, rs.getString());
        } catch (IllegalArgumentException e) {
            throw new SQLException("Unknown parameter type: " + rs.getString(), e);
        }
    }
}

Что вы можете затем использовать следующим образом:

public class XEnumTypeHandler extends CommonEnumTypeHandler<X> {
    public XEnumTypeHandler() {
        super(X.class);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...