有没有办法检查子类是否已通过泛型类型参数?

时间:2016-10-10 12:04:50

标签: java android generic-type-argument

我有一个超类(Android's Fragment):

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)没有传递泛型类型参数,则可以捕获异常。但是,我想知道是否有任何方法可以检查而不是捕获异常?或者这可能不是一个好的设计......

1 个答案:

答案 0 :(得分:0)

根据this StackOverflow帖子

  
    

通用信息在运行时删除,无法恢复。解决方法是在静态方法的参数中传递类T:

  
     

public class 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;
        }
}