Java如何将通用参数声明为任何接口

时间:2014-10-17 19:49:35

标签: java generics reflection

我正在尝试学习Java中的一些反思,但我遇到了麻烦。基本上我正在尝试创建一个非常通用的事件系统。是的我知道那里已经有很多但是这更像是一种学习练习而不是实际练习。无论如何,当我声明EventSource<PersonnameChangeListener, PersonNameChangeEvent>

的实例时,我一直收到以下错误
error: type argument PersonNameChangeListener is not within bounds of type-variable ListenerT
    private EventSource<PersonNameChangeListener,
  where ListenerT is a type-variable:
    ListenerT extends Class declared in class EventSource

所以我的问题是,“我如何声明我希望通用参数任何接口?”

提前谢谢你,

JEC

public interface PersonNameChangeListener extends EventListener
{
    public void nameChangeOccured(PersonNameChangeEvent event);
}

public class PersonNameChangeEvent extends EventObject
{
    private String m_OldName;
    private String m_NewName;

    public PersonNameChangeEvent(Object source,
                                    String oldName,
                                    String newName)
    {
        super(source);

        m_OldName = oldName;
        m_NewName = newName;
    }

    public String getOldName()
    {
        return m_OldName;
    }

    public String getNewName()
    {
        return m_NewName;
    }
}

public class EventSource<ListenerT extends Class, EventT>
{
    List<ListenerT> m_ListenerList;

    public EventSource()
    {
        m_ListenerList = new ArrayList<>();
    }

    public void addNameChangeListener(ListenerT listener)
    {
        m_ListenerList.add(listener);
    }

    public void removeNameChangeListener(ListenerT listener)
    {
        m_ListenerList.remove(listener);
    }

    private void fireNameChangedEvent(EventT event) throws IllegalAccessException,
                                                              InvocationTargetException
    {
        for (ListenerT listener : m_ListenerList)
        {
             Method[] methods = listener.getDeclaredMethods();
             for (Method method : methods)
             {
                 Class<?>[] parameterTypes = method.getParameterTypes();
                 final int parameterCount = method.getParameterCount();
                 if (parameterCount == 1
                     && parameterTypes[1].getTypeName().compareTo(event.getClass().getTypeName()) == 0)
                 {
                     try
                     {
                        method.invoke(this, event);
                     }
                     catch (IllegalAccessException | InvocationTargetException e)
                     {
                         throw e;
                     }
                     break;
                 }
             }
        }
    }
}

1 个答案:

答案 0 :(得分:1)

如果您不得不反思它以获得所需的方法,那么将ListenerT声明为泛型类型参数确实没有价值。我会完全删除type参数,只使用Object

重要提示:这样做只对学习反射API有意义,而不是在生产中这样做。我意识到你这么说,但我想再强调一点。