我有以下两行:
Map<String,Object>[] IEXDivMap = null;
IEXDivMap = new Map[IEXJsonArray.length()];
并得到警告:
The expression of type Map[] needs unchecked conversion to conform to Map<String,Object>[]
有没有办法解决这个问题?
更新:
我在评论中被问到为什么我们需要一个Map数组。我们将获得一系列哈希图,并将每个哈希图放置在map数组中。这是代码:
@SuppressWarnings("unchecked")
public static Map<String,Object>[] getDiv(String ticker) {
Map<String,Object>[] IEXDivMap = null;
try{
String url = "https://api.IEXtrading.com/1.0/stock/" + ticker + "/dividends/1y";
URL obj = new URL(url);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
int responseCode = con.getResponseCode();
if(responseCode == 404){
System.out.println("Ticker " + ticker + " NOT FOUND in getDiv()!");
return IEXDivMap;
}else if (responseCode != 200){
System.out.println("IEX Printing All Response Header for URL: " + obj.toString() + "\n");
Map<String, List<String>> map = con.getHeaderFields();
for(Map.Entry<String, List<String>> entry : map.entrySet()) {
System.out.println("IEX " + entry.getKey() + " : " + entry.getValue());
}
}
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuilder response = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
JSONArray IEXJsonArray = new JSONArray(response.toString());
IEXDivMap = new Map[IEXJsonArray.length()];
for (int i = 0; i < IEXJsonArray.length(); i++) {
IEXDivMap[i] = new HashMap<String,Object>();
JSONObject IEXJsonObject = IEXJsonArray.getJSONObject(i);
IEXDivMap[i].put("exDate",IEXJsonObject.getString("exDate"));
IEXDivMap[i].put("amount",IEXJsonObject.getString("amount"));
//System.out.println(IEXDivMap[i]);
System.out.println(IEXDivMap[i].get("exDate") + " 0 " + IEXDivMap[i].get("amount"));
}
}catch(Exception e){
System.out.println("FATAL ERROR: Something went wrong in getDiv " + e.getMessage());
System.exit(0);
}
return IEXDivMap;
}
答案 0 :(得分:4)
不幸的是,不可能以干净的方式解决此问题。
干净的解决方案是创建通用数组,但由于类型擦除而无法实现。
考虑以下数组示例:
Object[] arr = new String[1];
arr[0] = 10;
结果为ArrayStoreException
。
现在想象一下允许创建通用数组:
Map<String, String>[] map = new Map<>[1]; // This is illegal
Object[] objects = map;
objects[0] = new HashMap<Integer, Integer>(); // No ArrayStoreException
编译器警告说,可以将任何Map
放入数组,并且编译器和运行时都不能检查它。因此警告
引用Java generics faq可以使用:
- 原始类型的数组
- 无界通配符参数化类型的数组
- 集合而不是数组
我个人强烈建议您考虑使用List
:
List<Map<String, Object>> list = new ArrayList<>();
答案 1 :(得分:2)
您无法避免该警告。数组创建仅允许将原始类型用作元素类型。我确定Java专家决定不在那里允许泛型是有原因的,但我不知道该原因。
因此,如果您真的想要一个Map<String,Object>
元素数组(由于某种原因不能使用List
),则可以声明具有该泛型类型的变量,但是您将始终在存储刚创建的数组时会收到该警告,因为该数组只能具有原始类型。
但这只是一个警告,您的代码将运行得很好。这是一个警告,而不是一个错误,这意味着有些事情需要开发人员注意,因为编译器无法确定是否可以。
那么导致警告的问题是什么?
在运行时,Map<String,Object>[]
仅仅是Map[]
,因为在编译过程中会擦除泛型类型。因此,创建数组会产生正确的数组运行时类型,并且您不会从该分配中获得ClassCastException
。仅在编译时检查泛型规则:编译器有责任确保分配给Map[]
变量的运行时Map<String,Object>[]
仅包含其中字符串用作键的Maps和对象作为值(当然null
值也可以作为数组元素)。
现在,如果您将编译时的Map[]
值分配给Map<String,Object>[]
变量,
Map[] rawArray = ...;
Map<String,Object>[] generic Array = rawArray;
编译器不知道rawArray
中包含的映射使用什么类型的键和值,因此他正确地警告您这种类型不兼容的风险。但是,对于新创建的new Map[n]
,
Map<String,Object>[] genericArray = new Map[5];
编译器根本不够聪明,无法看到此数组仅包含其初始null
值,因此完全符合Map<String,Object>[]
的要求。该语句实际上并不包含任何与类型相关的风险,只是编译器不够智能而无法理解。
因此,我的建议是忽略警告或在此处放置适当的@SuppressWarnings
注释,并说明为什么有理由抑制警告。遗憾的是我们无法将@SuppressWarnings
注释应用于单个语句,因此您可能希望将数组创建重构为自己的方法,因此@SuppressWarnings
注释仅适用于该操作而不是整个方法。
答案 2 :(得分:0)
对于您的用例,我没有看到在像List
这样的集合上使用数组的内在优势。只需将您的代码更改为使用List
即可,这将确保类型安全,并且无需进行任何类型的索引等操作。
将要改变的大事情:
如何声明退货类型
public static List<Map<String,Object>> getDiv(String ticker)
如何实例化持有人
List<Map<String,Object>> IEXDivMap = new ArrayList<>();
如何填充地图(有点,您只需更改其引用方式即可)
Map<String, Object> divMap = new HashMap<>();
答案 3 :(得分:0)
无法避免警告。
通过将其显式转换为适当的参数化数组类型,可以避免未检查的转换警告:
IEXDivMap = (Map<String, Object>[]) new Map[IEXJsonArray.length()];
或
IEXDivMap = (Map<String, Object>[]) new Map<?,?>[IEXJsonArray.length()];
但是它将导致产生未经检查的强制转换警告,因此您将一个警告换成另一个。
答案 4 :(得分:-2)
也许是这样吗?
import java.util.Map;
import java.util.HashMap;
public class test {
public static void main(String[] args) {
class MyMap extends HashMap<String,Object> { }
MyMap[] IEXDivMap = null;
IEXDivMap = new MyMap[2];
}
}