枚举是原始类型。对泛型类型 Enum 的引用应该进行参数化。

huangapple go评论77阅读模式
英文:

Enum is a raw type. References to generic type Enum<E> should be parameterized

问题

我在我的Java代码中收到以下警告...

枚举是原始类型。对泛型类型Enum&lt;E&gt;的引用应该是参数化的。

我不确定纠正此警告的适当方法是什么...

触发警告的代码是方法process上的以下类定义...

这个抽象类的实现类返回不同类型的枚举,而Message抽象类的用户只是在枚举上调用ordinal()方法,而不知道Enum的基本类型。

public abstract class Message {

    private User user;

    // 返回用于工厂构造的消息的字符串名称
    public abstract String getName();

    // 如果设置为true,框架将自动检查根json节点中是否存在firebase idToken,
    // 然后进行身份验证并调用setUser以使用内部用户。
    // 如果实现类设置requiresUserAuth返回true,则可以安全地在process方法中调用getUser。
    public abstract boolean requiresUserAuth();

    // 处理消息的json内容并返回特定于消息的int结果代码
    // 使用json响应数据填充ObjectNode响应。
    public abstract Enum process(JsonNodeThrows contents , ObjectNode response) throws JsonException;
    
    // 省略访问修饰符以使用默认包保护
    void setUser(User user) 
    {
        this.user = user;
    }

    protected User getUser()
    {
        if (!requiresUserAuth())
            throw new RuntimeException("Message.getUser() - 当实现消息类的requiresUserAuth方法返回false时调用了getUser。");
        if (user == null)
            throw new RuntimeException("Message.getUser() - 在用户为null时调用了getUser。");
        return user;
    }
}
英文:

I am getting the following warning in my java code...

Enum is a raw type. References to generic type Enum&lt;E&gt; should be parameterized

I am not sure what the proper course of action is to rectify this warning...

My code that triggers the warning is the following class definition on the method process...

The implementing classes of this abstract class return varying types of enums, and the user of the Message abstract class simply calls ordinal() on the enum, without knowing anything about the underlying type of Enum.

public abstract class Message {

    private User user;

    // return string name of message that will be use for factory construction
    public abstract String getName();

    // if set to true, the framework will automatically check for a firebase idToken in the root json node
    // it will then authenticate and call setUser with the internal user.
    // If implementing class set requiresUserAuth to return true, then is it safe to call getUser in the 
    // process method.
    public abstract boolean requiresUserAuth();

    // process the json contents of the message and return the int result code specific for the message
    // populate ObjectNode response with the json response data.        
    public abstract Enum process(JsonNodeThrows contents , ObjectNode response) throws JsonException;
    
    // omit access modifier to use default package protected
    void setUser(User user) 
    {
        this.user = user;
    }

    protected User getUser()
    {
        if (!requiresUserAuth())
            throw new RuntimeException(&quot;Message.getUser() - called getUser when implementing message class requireUserAuth method returns a value of false.&quot;);
        if (user == null)
            throw new RuntimeException(&quot;Message.getUser() - called getUser when user is null.&quot;);
        return user;
    }
}

答案1

得分: 5

如果方法可以返回不同的枚举值,使用:

public abstract Enum<?> process(... 

如果调用方知道预期的枚举类型,使用:

public abstract <T extends Enum<T>> T process(... 
英文:

If method can return various enums, use

public abstract Enum&lt;?&gt; process(...

If the caller knows which enum to expect, use

public abstract &lt;T extends Enum&lt;T&gt;&gt; T process(...

答案2

得分: 0

> Enum是一个原始类型。对泛型类型Enum&lt;E&gt;的引用应该加上参数化&hellip;

Enum&lt;E extends Enum&lt;E&gt;&gt;是一个泛型类。这就是警告信息所指的,通过告诉你「Enum&lt;E&gt;应该被参数化」。但是这个警告是一个误导。

> 「*&hellip;我不确定纠正这个警告的正确方法是什么&hellip;」

你的 Message.process() 方法的设计可能需要重构。

> 「*&hellip;Message抽象类的使用者只需在枚举上调用ordinal(),而不需要了解Enum的底层类型&hellip;」

如果你确信只会调用 Enum.ordinal( ),并且如果你能够控制在你的应用程序API中暴露哪些 Enums,那么你有一个选项是引入一个接口(比如 Ordinalable),该接口指定了 ordinal() 方法。然后你的应用程序中的所有 Enums 都可以实现 Ordinalable(或者任何你想给它的名称)。

类似于这样…

public interface Ordinalable { 
    
    int ordinal( );
}



enum Foo implements Ordinalable { 
    A, B, C  ;
}



enum Bar implements Ordinalable { 
    
    UNOS, DOS, TRES;
    
}



public abstract class Message { 
    
    public abstract Ordinalable process(  ){  }
    
}



public class AMessage extends Message {
    
    @Override
    public Ordinalable process( ){ 
        return Foo.A;
    }
}



public class BMessage extends Message { 
    
    @Override
    public Ordinalable process( ){ 
        return Foo.B;
    }
}



public class DuoMessage extends Message { 
    
    @Override
    public Ordinalable process( ){ 
        return Bar.DOS;
    }
}

…你可以这样调用…

Message msg = new AMessage( );
        
int ordinal = msg.process( ).ordinal( );

msg = new BMessage( );
        
ordinal = msg.process( ).ordinal( );

msg = new DuoMessage( );
        
ordinal = msg.process( ).ordinal( );

你可以在这里看到这种方法的试验实现

英文:

> Enum is a raw type. References to generic type Enum&lt;E&gt; should be parameterized&hellip;

Enum&lt;E extends Enum&lt;E&gt;&gt; is a generic class. That's what the warning message is referring to by telling you „Enum&lt;E&gt; should be parameterized“. But that warning is a red herring.

> „&hellip;I am not sure what the proper course of action is to rectify this warning&hellip;

The design of your Message.process() method should probably be refactored.

> „&hellip;the user of the Message abstract class simply calls oridinal() on the enum, without knowing anything about the underlying type of Enum&hellip;

If you are certain that Enum.ordinal( ) is all that will ever be called, and if you have control over what Enums will be exposed in your app's API, then one option you have is to introduce an interface (an Ordinalable, say) that specifies the ordinal() method. Then all your app's Enums could implement Ordinalable (or any name you want to give it).

Something like…

public interface Ordinalable { 

    int ordinal( );
}

…

enum Foo implements Ordinalable { 
    A, B, C … ;
}

…

enum Bar implements Ordinalable { 

    UNOS, DOS, TRES;

}

…

public abstract class Message { 
    …
    public abstract Ordinalable process( … ){ … }
    …
}

…

public class AMessage extends Message {

    @Override
    public Ordinalable process( ){ 
        return Foo.A;
    }
}

…

public class BMessage extends Message { 

    @Override
    public Ordinalable process( ){ 
        return Foo.B;
    }
}

…

public class DuoMessage extends Message { 

    @Override
    public Ordinalable process( ){ 
        return Bar.DOS;
    }
}

…Which can be called like…

Message msg = new AMessage( );
    
int ordinal = msg.process( ).ordinal( );
…
msg = new BMessage( );
    
ordinal = msg.process( ).ordinal( );
…
msg = new DuoMessage( );
    
ordinal = msg.process( ).ordinal( );
…

You can see an experimental implementation of that approach here.

huangapple
  • 本文由 发表于 2020年8月30日 09:15:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/63653145.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定