在转换为泛型类型时,Java中的警告

Law*_*Dol 8 java generics warnings

我有一些通用代码,我无法弄清楚如何合法地阻止警告; 我目前正在使用@SuppressWarnings("unchecked"),因为似乎在没有警告的情况下无法完成转换泛型类型.

我怎样才能摆脱注释?

我有的是:

public MyObject(SharedContext<Object> ctx) {
    super(ctx); // set protected field 'context'
    ...
    context.set("Input Fields"  ,Collections.synchronizedMap(new TreeMap<String,Pair<String,Boolean>>(String.CASE_INSENSITIVE_ORDER)));
    context.set("Output Fields" ,Collections.synchronizedMap(new TreeMap<String,String>              (String.CASE_INSENSITIVE_ORDER)));
    context.set("Event Registry",new EventRegistry(log)                                                                              );
    }

@SuppressWarnings("unchecked")
protected void startup() {
    inputFields     =(Map<String,Pair<String,Boolean>>)context.get("Input Fields"  ,null);
    outputFields    =(Map<String,String>              )context.get("Output Fields" ,null);
    eventRegistry   =(EventRegistry                   )context.get("Event Registry",null);
    ...
    }
Run Code Online (Sandbox Code Playgroud)

受保护的变量上下文是类型SharedContext<Object>.

如果没有注释,编译器会发出警告:

...\MyClass.java:94: warning: [unchecked] unchecked cast
found   : java.lang.Object
required: java.util.Map<java.lang.String,com.mycompany.Pair<java.lang.String,java.lang.Boolean>>
    inputFields     =(Map<String,Pair<String,Boolean>>)context.get("Input Fields"  ,null);
                                                                  ^
...\MyClass.java:95: warning: [unchecked] unchecked cast
found   : java.lang.Object
required: java.util.Map<java.lang.String,java.lang.String>
    outputFields    =(Map<String,String>              )context.get("Output Fields" ,null);
Run Code Online (Sandbox Code Playgroud)

Law*_*Dol 3

经过一些进一步的研究,我相信我已经找到了一种合理的替代方案,它至少将抑制注释限制为仅一个全局静态实用程序方法来执行未经检查的转换。

下面的独立测试程序应该足够清晰:

public class Generics
{

static public void main(String[] args) {
    Generics.test();
    }

static private void test() {
    Map<String,Object> ctx=new TreeMap<String,Object>();
    Map<String,Object> map=new TreeMap<String,Object>();
    Map<String,Object> tst;

    ctx.put("Test",map);
    tst=uncheckedCast(ctx.get("Test"));
    }

@SuppressWarnings({"unchecked"})
static public <T> T uncheckedCast(Object obj) {
    return (T)obj;
    }

}
Run Code Online (Sandbox Code Playgroud)

另一篇博客建议对此实用方法进行改进:

@SuppressWarnings("unchecked") 
public static <T, X extends T> X uncheckedCast(T o) {
    return (X) o;
    }
Run Code Online (Sandbox Code Playgroud)

强制返回的内容成为传入参数的子类。

假设我将 uncheckedCast 放入公共实用程序类 GenUtil 中,问题中的启动方法将不会发出(无用的)警告,如下所示:

protected void startup() {
    inputFields  =GenUtil.uncheckedCast(context.get("Input Fields"  ,null));
    outputFields =GenUtil.uncheckedCast(context.get("Output Fields" ,null));
    eventRegistry=GenUtil.uncheckedCast(context.get("Event Registry",null));
    ...
    }
Run Code Online (Sandbox Code Playgroud)

  • 就我个人而言,我认为“GenUtil.uncheckedCast”比抑制特定警告更糟糕:无法保证该实用程序方法被负责任地使用,即以不会导致堆污染的方式使用,但程序员不再被提示尝试更稳健的实施的警告。(有时,尽管并非总是如此,是可能的......) (4认同)
  • 编译器不会相信你的话,它会发出运行时检查。强制转换可以(有时确实)用作对象类型的断言。该警告告诉您此检查不完整,因此不能依赖。 (2认同)