【问题标题】:Java generic method to get value of type by using switch on typeJava泛型方法通过使用开关类型来获取类型的值
【发布时间】:2014-01-06 08:43:18
【问题描述】:

我想在下面有这样的东西(例如我将如何在 C# 中执行此操作),以从 SQLiteDB 获取类型值:

private T GetValueFromDB<T>(String colName) {
    object returnValue = null;

    switch (typeof(T)) {
        case Boolean:
            returnValue = dbData.getInt(colName) == 1;
            break;

        case Int32:
            returnValue = dbData.getInt(colName);
            break;

        case Int64:
            returnValue = dbData.getLong(colName);
            break;

        case String:
            returnValue = dbData.getString(colName);
            break;
    }
    return (T)returnValue;
}

是否有可能(使用 switch case 或 if else)在 Java 中实现它?

【问题讨论】:

  • 没有办法在运行时获取泛型类型参数的实际类。前段时间遇到过同样的问题。
  • 我不明白这个函数的含义。你会如何使用这个功能?而在Java中,方法的定义应该是这样的:private T FOO(String colName)

标签: java generics methods switch-statement typeof


【解决方案1】:

如果你在调用方法时已经知道类型,你可以这样做:

private T GetValueFromDB<T>(String colName, Class<T> returnType) {

    if(returnType.equals(Boolean.class)) {
        return (T)(dbData.getInt(colName) == 1);
    } else if(returnType.equals(Int32.class)) {
        // and so on
    }
}

【讨论】:

  • 这正是我想要的。谢谢。
  • 我在 Android 中编程时尝试做类似的事情,但出现错误 - 无法从布尔值转换为 T. public T get (String key, Class returnType) { if (!sharedPreferences .contains(key)) 返回空值; else { if(returnType.equals(Boolean.class)) { return (T) (sharedPreferences.getBoolean(key, false));
  • 我遇到了同样的错误。无法从 int 转换为 T。这种方法真的有效吗?还是我错过了什么?
  • 好的,问题出在自动装箱上。我试图将 int 转换为 T。如果我将 int 保存在 Integer 变量中,然后将其转换为 T,它可以正常工作。哦,Java!
【解决方案2】:

Java 使用 类型擦除,因此无法在运行时确定 T 的类型。

【讨论】:

  • ...所以如果你想实现它,你必须在你的函数中添加另一个参数(Class clazz)并用它来比较实际的类。
【解决方案3】:

我做了接口切换,也许对某人有用:

new ISwitch(pagerCtrl.getPager().getFragmentByID(fragment_id))

      .addCase(new ISwitch.CaseListener<Type1>() {
        @Override
        public void Case(Type1 instance) {

        }
    }).addCase(new ISwitch.CaseListener<Type2>() {
        @Override
        public void Case(Type2 instance) {

        }
    }).addDefault(new ISwitch.DefaultListener() {
        @Override
        public void Default() {

        }
    }).build();



public class ISwitch {

    public interface CaseListener<T> {
        void Case(T instance);
    }

    public interface DefaultListener {
        void Default();
    }

    Object value;
    LinkedList<CaseListener<?>> col = new LinkedList<>();
    DefaultListener defaultListener;


    public ISwitch(Object value) {
        this.value = value;
    }

    public void build() {

        boolean wasNotifiedMinimumOnce = false;
            for (CaseListener<?> c : col) {

                try {
                    CaseListener<Object> l = (CaseListener<Object>) c;
                    l.Case(value);
                    wasNotifiedMinimumOnce = true;
                    break;
                } catch (ClassCastException e) {

                }
            }

        if ( !wasNotifiedMinimumOnce ) {
            if ( defaultListener != null ) {
                defaultListener.Default();
            }
        }
    }



    public ISwitch addCase(CaseListener<?> caseListener) {

        col.add(caseListener);
        return this;
    }

    public ISwitch addDefault(DefaultListener defaultListener) {
        this.defaultListener = defaultListener;
        return this;
    }


}

实现的小缺点是我们无法检查 instanceof,这就是我在演员表中捕获它的原因。对我来说这没什么大不了的,但它可能是每秒执行 XXXXXX 次 Java 服务器代码的性能问题。

【讨论】:

    猜你喜欢
    • 2011-05-11
    • 1970-01-01
    • 2013-04-17
    • 2022-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多