[英]Warnings in Java when casting to a generic type
我有一些通用代碼,我無法弄清楚如何合法地阻止警告; 我目前正在使用@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);
...
}
受保護的變量上下文是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);
經過一些進一步的研究后,我相信我找到了一個合理的替代方案,它至少將抑制注釋限制為一個全局靜態實用方法來進行未經檢查的強制轉換。
隨后的自包含測試程序應該足夠清楚:
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;
}
}
另一篇博客建議改進這種實用方法:
@SuppressWarnings("unchecked")
public static <T, X extends T> X uncheckedCast(T o) {
return (X) o;
}
強制返回的內容是傳入的參數的子類。
假設我將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));
...
}
可以通過定義擴展泛型Map<String, Pair<String, Boolean>>
並將其存儲在SharedContext
而不是通用TreeMap
的非泛型類來消除第一個未經檢查的強制轉換,例如(使用來自Guava的 ForwardingMap ):
class InputFieldMap extends ForwardingMap<String,Pair<String,Boolean>> {
private final Map<String,Pair<String,Boolean>> delegate =
Maps.newTreeMap(String.CASE_INSENSITIVE_ORDER);
protected Map<String,Pair<String,Boolean>> delegate() { return delegate; }
}
// ...
context.set("Input Fields" ,Collections.synchronizedMap(new InputFieldMap()));
// ...
inputFields =(InputFieldMap)context.get("Input Fields" ,null);
outputFields =(Map<?,?> )context.get("Output Fields" ,null);
您可以以相同的方式使第二個強制轉換安全,或者(假設您只是讀取不修改它的映射)按原樣使用映射(使用通配符參數)並將值轉換為每個查找的字符串:
String bar = String.valueOf(outputFields.get("foo"));
或包裹地圖:
Map<?, String> wrappedOutputFields =
Maps.transformValues(outputFields, Functions.toStringFunction());
// ...
String bar = wrappedOutputFields.get("foo");
SharedContext對象是您編寫的對象嗎? 如果是這樣,是否可以用特定字段替換通用String-> Object映射?
例如。
context.setInputFields(...)
context.setOutputFields(...)
context.setEventRegistry(...)
context.getInputFields()
etc.
對我來說,通用的hold-all上下文對象似乎總是不太完美。 特別是使用泛型和未經檢查的強制轉換消息。
或者,您可以創建一個名為SoftwareMonkeyContext的包裝器對象,該對象具有上述特定的setter / getter方法,並在內部使用您的GenUtil.uncheckedCast方法。 這可以防止您需要在代碼中的多個位置使用GenUtil.uncheckedCast。
如何分配context
變量? 它來自參數ctx,它的類型是:
SharedContext<Object>
?
如果是這樣,那就是你的問題,因為當你做了一個讓你沒有有效輸入你得到的東西。
您使用的是哪個版本的編譯器? 使用Java 6編譯器(Sun JDK windows),我沒有看到詳細的警告。 我只在使用'-Xlint:unchecked'標志時才收到警告信息。
嘗試-Xlint:-unchecked並告訴我們它是否可以解決您的問題。 有關旗幟的更多信息,
http://java.sun.com/javase/6/docs/technotes/tools/windows/javac.html
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.