Java 如何将泛型参数声明为任意接口(interface)

标签 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

所以我的问题是,“我如何声明我想要一个通用参数是任何接口(interface)?”

提前谢谢您,

jack

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

最佳答案

如果您无论如何都必须反射(reflection)它以获得所需的方法,那么将 ListenerT 声明为泛型类型参数确实没有任何值(value)。我将完全删除类型参数并仅使用 Object

重要说明:这样做仅对于学习反射 API 有意义,对于在生产中执行此操作没有意义。我知道你这么说,但我想再次强调这一点。

关于Java 如何将泛型参数声明为任意接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26432458/

相关文章:

java - 使用 MongoDB 进行 Hibernate 配置

java - 根据成员变量或映射函数返回子列表

java - Orika 通用集合自定义映射

去reflect.MakeFunc。如何返回 err=nil 作为reflect.Value?

java - 如何使用反射检查对象的通用类型?

c# - 有没有办法在 C# 中动态获取方法名称?

java - 创建字节数组缓存

java - 用java接收和处理电子邮件

java - 一起分享音频和文本

java - 如何使用运行时类型信息调用泛型方法?