2016-10-10 76 views
2

我有一個超類(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

回答

0

根據this StackOverflow

通用信息是在運行時刪除,無法恢復。一種解決方法是通過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

相關問題