【问题标题】:Passing Interface Class as a Parameter in Java在 Java 中将接口类作为参数传递
【发布时间】:2011-02-21 00:31:52
【问题描述】:

我有一个界面:

public interface IMech {

}

以及实现它的类

public class Email implements IMech {

}

以及实现此方法的第三个类:

public void sendNotification( Class< IMech > mechanism ){
}

现在我正在尝试像这样调用该方法

foo.sendNotification(Email.class);

但我不断收到异常消息:

The method sendNotification(Class<IMech>) in the type RemediationOperator is not applicable for the arguments (Class<Email>)

如果它接口那个类,这不应该工作吗?

【问题讨论】:

  • 什么是 EmailNotification 类以及什么实现或扩展它?
  • 你真的要传递 Class 对象,而不是实现 IMech 接口的某个类的实例吗?这当然可能是您想要的,但从您提供的信息中我无法判断这是故意还是设计错误。
  • 对不起,我把一些类名缩短了...EmailNotification 是Email 类

标签: java interface


【解决方案1】:

也许你需要

public void sendNotification( Class<? extends IMech> mechanism ) { 

【讨论】:

    【解决方案2】:

    因为Class&lt;IMechanism&gt;Class&lt;EmailNotification&gt; 这两个类本身通过继承相关,即使IMechanismEmailNotification

    您需要让您的方法接受Class&lt;? extends IMechanism&gt;

    【讨论】:

      【解决方案3】:

      您的参数机制需要使用有界通配符,如下所示:

      public void sendNotification(Class extends IMech> 机制){ }

      引用泛型教程link text

      一般来说,如果 Foo 是一个子类型 Bar 的(子类或子接口),以及 G 是一些泛型类型声明,它 不是 G 是 G的亚型。

      【讨论】:

        【解决方案4】:

        泛型在 Java 中不是这样工作的。您真正需要做的是将方法签名更改为

        public void sendNotification( Class< ? extends IMech > mechanism ){
        }
        

        或者是super而不是extends...让我参考Effective Java的Generics chapter...

        编辑: 有效的 Java 说:

        这里有一个助记符来帮助你 记住要使用的通配符类型: PECS 代表生产者扩展,消费者超级。

        我假设这将产生 IMech 实例,并且 extends 是正确的。

        【讨论】:

          【解决方案5】:

          正确的做法是:

          public void sendNotification(IMech mechanism) {
          
          }
          

          所以请大家阅读一些关于接口的java教程!

          【讨论】:

            【解决方案6】:

            接口背后的理念是您不需要知道它是哪一个。无论实现如何,您都应该能够简单地传入一个 IMech 并调用其功能。考虑以下几点:

            public interface IMech {
                void sendMessage();
            }
            
            public class Email implements IMech {
                @Override
                void sendMessage() { /* stuff here to send email */ }
            }
            

            这是接口的典型使用模式。如果您只是将它用作一个选项,也许您应该考虑使用枚举来代替。

            enum IMech { EMAIL, INSTANT_MESSAGE, SNAIL_MAIL, YELL_OVER_CUBICLE }
            
            public void sendNotification( IMech mechanism ){
                switch(mechanism) {
                    case IMech.EMAIL: // do email .. etc
                }
            }
            
            foo.sendNotification(IMech.EMAIL);
            

            现在我知道这些并不能直接回答您的问题,但这些是典型的使用形式,通常表明更具适应性的设计模式。毕竟,你真的需要发送一个类对象吗?如果您只是确定使用哪种机制,枚举似乎更合适。

            【讨论】:

              【解决方案7】:

              如果你这样做,IMO 会更干净:

              public void sendNotification( IMech mechanism ){
              }
              

              您始终可以在方法中获取类。

              【讨论】:

                猜你喜欢
                • 2013-04-09
                • 1970-01-01
                • 2017-05-29
                • 2011-02-02
                • 1970-01-01
                • 2016-11-22
                • 2011-12-04
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多