枚举常量的编译器警告

时间:2016-05-19 16:26:14

标签: java

我在使用带有enum常量的泛型时遇到了困难。我收到编译器警告:

  

未选中调用'handle(M)'作为原始类型'Test.MessageHandler'的成员

在下面的代码段的最后一行。

如何删除此警告的任何提示都将受到高度赞赏。

public class Test {
    private enum MessageNumber {
        LOGIN,
        LOGOUT
    }

    private interface Message {}
    private static class LoginMessage implements Message {}
    private static class LogoutMessage implements Message {}

    private interface MessageHandler<M extends Message> {
        void handle(M msg);
    }

    private static class LoginMessageHandler implements MessageHandler<LoginMessage> {
        public void handle(LoginMessage msg) {System.out.println(msg);}
    }
    private static class LogoutMessageHandler implements MessageHandler<LogoutMessage> {
        public void handle(LogoutMessage msg) {System.out.println(msg);}
    }

    private static final Map<MessageNumber, MessageHandler> HANDLERS = new ConcurrentHashMap<MessageNumber, MessageHandler>() {{
        put(MessageNumber.LOGIN, new LoginMessageHandler());
        put(MessageNumber.LOGOUT, new LogoutMessageHandler());
    }};

    public static void main(String[] args) {
        MessageHandler loginHandler = HANDLERS.get(MessageNumber.LOGIN);
        loginHandler.handle(new LoginMessage()); //Compiler warning: Unchecked call to 'handle(M)' as a member of raw type 'Test.MessageHandler'
    }
}

2 个答案:

答案 0 :(得分:1)

您已将loginHandler声明为原始类型 - 即无类型:

MessageHandler loginHandler = HANDLERS.get(MessageNumber.LOGIN);

相反,键入登录变量,并添加一个强制转换:

MessageHandler<LoginMessage> loginHandler = 
    (MessageHandler<LoginMessage>)HANDLERS.get(MessageNumber.LOGIN);

你仍然会收到一个警告,只是在另一条线上。

答案 1 :(得分:0)

显而易见的是,您收到了警告,因为您没有在exit_script() { status=$? if [[ $status -eq 0 ]] ; then echo "exit from script with success" else echo "exit with error..." fi >&2 # Now you can just make one, all-purpose call to exit exit $status } 地图中为MessageHandler指定类型参数。

但是如果你尝试指定它,你最终会得到HANDLERS,然后你就无法在不进行未经检查的演员的情况下调用Map<MessageNumber, MessageHandler<? extends Message>>

这一切告诉你的是 Java无法检查你的类型静态 的正确性。

您可以做的是在运行时执行检查。如果你想自己检查一下,而不是让代码可能触发handle(),你可以这样做:

ClassCastException