是否有任何方法来检查子类是否已通过泛型类型参数?

问题描述:

我有一个超类(Android的碎片):是否有任何方法来检查子类是否已通过泛型类型参数?

public abstract class BaseFragment<T> extends Fragment { 

    private T mListener; 

    public T getFragmentInteractionListener(){ 
     return mListener; 
    } 

    @Override 
    public void onAttach(Activity activity) { 
     super.onAttach(activity); 
     castFragmentInteractionListener(); 
    } 

    void castFragmentInteractionListener(){   
     Type superClassType = this.getClass().getGenericSuperclass(); 
     if (superClassType instanceof ParameterizedType) { 
      try { 
       // I want to know if there is any way to check if the type argument has 
       // been set? So I can avoid the exception. 
       Class<T> listenerClazz = (Class<T>) ((ParameterizedType) superClassType).getActualTypeArguments()[0]; 

       mListener = FragmentUtils.castFragmentInteractionListener(context, this, listenerClazz); 

      } catch (Exception e) { 

      } 
     } 

    } 
} 

以及它的衍生一些子类。

public class FragmentDoesNotNeedListener extends BaseFragment { 


} 

public class FragmentHasListener extends BaseFragment<FragmentInteractionListener> { 

    interface FragmentInteractionListener { 
     void onClick(); 
     void onExit(); 
    } 

    @Override 
    public void onActivityCreated(Bundle savedInstanceState) { 
     super.onActivityCreated(savedInstanceState); 
     getFragmentInteractionListener().onClick(); 

    } 

} 

从本质上讲,我希望每个片段从BaseFragment派生,大多有可以从自己被称为侦听器。我不想重复代码来投射它,因此创建基本片段并使用泛型类型。但是,一些片段不需要使用侦听器。但我不知道如何检查参数类型是否给出。

在BaseFragment类中,方法castFragmentInteractionListener将类转换为类字段,然后使用它将类转换为侦听器。如果子类(FragmentDoesNotNeedListener)没有通过泛型类型参数,因为异常将被捕获,这是可以的。但是,我想知道是否有任何方法来检查而不是捕获异常?或者,也许这不是一个好的设计...

+0

为什么你需要的?你不能在Child中使用模板模式吗? – Blackbelt

根据this *

通用信息是在运行时删除,无法恢复。一种解决方法是通过T级的静态方法的参数:

公共类MyGenericClass {

private final Class<T> clazz; 

public static <U> MyGenericClass<U> createMyGeneric(Class<U> clazz) { 
    return new MyGenericClass<U>(clazz); 
} 

protected MyGenericClass(Class<T> clazz) { 
    this.clazz = clazz; 
} 

public void doSomething() { 
    T instance = clazz.newInstance(); 
} } 

它的丑陋,但它的工作原理。

或者你可以使用简单的执行上类,你实际上检查

public abstract class BaseFragment<T> extends Fragment { 

//... 

public static Class classType(Class cls) 
     { 
      if(cls.equals(FragmentDoesNotNeedListener.class)) 
       return FragmentDoesNotNeedListener.class; 
      else 
       if (cls.equals(FragmentHasListener.class)) 
        return FragmentHasListener.class; 
      //else 
       // if(....) 

      else 
       return null; 
     } 
} 
+0

在我的情况下,这不是一个好的解决方案。因为我有30〜40个子片段....但是,我用来创建一个使用Class作为参数的注释。恩。 @ListenerClass(clazz所= Fragment1Listener.class)。但是这不是我喜欢的解决方案,因为我不想将Fragment1Listener放置两次:一个作为注释参数,另一个作为泛型类型参数。 – Arst