简体   繁体   English

java泛型:运行时类型检查以确定策略

[英]java generics: runtime type-checking to determine a strategy

how may I select a different method based upon a Generic type? 如何根据Generic类型选择不同的方法?

Simply I have a class parametrized with a generic type and I have to select the correct PreparedStatement setter according to the T type: 简单地说,我有一个使用泛型类型参数化的类,我必须根据T类型选择正确的PreparedStatement setter:

Class CustomFieldsTypeManager<T> {
   ArrayList<T> data;

   public void setUpStatement(PreparedStatement st){
      ...
      if ( **T==String** ){
         st.setString(index, (String) data<T>.get(dt_index);
      } else if ( **T==Integer** ){
         st.setInt(index, (String) data<T>.get(dt_index);
      }
      ...
   }
}

Because of type erasure that information on generics is lost at runtime. 由于类型擦除,泛型信息在运行时丢失。 You should try to exploit parametric polymorphism in a different way, by providing specialization of the classes: 您应该尝试通过提供类的特化来以不同的方式利用参数多态:

class CustomFieldsTypeManager<T> {
   ArrayList<T> data;

   abstract void setUpStatement(PreparedStatement st);
}

class StringCustomFieldsTypeManager extends CustomFieldsTypeManager<String> {
   void setUpStatement(PreparedStatement st) {
     st.setString(index, data.get(dt_index)); // data it's already an ArrayList<String>
   }
}

There are also ways to check it at runtime but this kinda defeats the good points of generics an inheritance even if they're as safe as this solution (must they must be correctly written). 还有一些方法可以在运行时检查它,但即使它们像这个解决方案一样安全(必须正确编写),这种方式也会破坏泛型的继承优点。

You're looking for instanceof : 你正在寻找instanceof

if ( data.get(dt_index) instanceof String ) {
    //...
}

You can't. 你不能。 But what you could do, is: 但你能做的是:

class CustomFieldsTypeManager<T> {
    private Class<T> type;
    public CustomFieldsTypeManager(Class<T> type) {
        this.type = type;
    }
}

Then: 然后:

CustomFieldsTypeManager<String> m = new CustomFieldsTypeManager<String>(String.class);

And finally: 最后:

public void setUpStatement(PreparedStatement st) {
    if (type.equals(String.class)){
        st.setString(index, (String) data<T>.get(dt_index);
    } else if (type.equals(Integer.class)){
        st.setInt(index, (String) data<T>.get(dt_index);
    }
}

Or, simply use the PreparedStatement#setObject method instead of the ones you're using. 或者,只需使用PreparedStatement#setObject方法而不是您正在使用的方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM