当long值传递给get方法时,使用整数作为键的映射返回null

use*_*124 4 java collections

import java.util.HashMap;
import java.util.Map;

public class StackOverFlowQuestion {

private static final int ERROR_CODE100 = -100;
private static final int ERROR_CODE101 = -101;
private static final int ERROR_CODE102 = -102;
private static final int ERROR_CODE103 = -103;
private static final int ERROR_CODE104 = -104;

public enum ErrorDetails {

    ERROR_CODE_100(ERROR_CODE100, "Error code 100 Desc", false),

    ERROR_CODE_101(ERROR_CODE101, "Error code 101 Desc", false),

    ERROR_CODE_102(ERROR_CODE102, "Error code 102 Desc", true),

    ERROR_CODE_103(ERROR_CODE103, "Error code 103 Desc", false),

    ERROR_CODE_104(ERROR_CODE104, "Error code 104 Desc", true);

    private int errorCode;
    private String errorMsg;
    private boolean canRetry;

    private ErrorDetails(int errorCode, String errorMsg, boolean canRetry) {
        this.errorCode = errorCode;
        this.errorMsg = errorMsg;
        this.canRetry = canRetry;
    }

    public String getErrorMsg() {
        return this.errorMsg;
    }

    public boolean canRetry() {
        return this.canRetry;
    }

    public String toString() {
        return "Error code : " + errorCode + ", errorMsg : " + errorMsg
                + ", canRetry : " + canRetry;
    }
}

private Map<Integer, ErrorDetails> errorMap;

public StackOverFlowQuestion() {
    System.out.println("StackOverFlowQuestion.StackOverFlowQuestion()");

    errorMap = new HashMap<Integer, StackOverFlowQuestion.ErrorDetails>();

    errorMap.put(ERROR_CODE100, ErrorDetails.ERROR_CODE_100);
    errorMap.put(ERROR_CODE101, ErrorDetails.ERROR_CODE_101);
    errorMap.put(ERROR_CODE102, ErrorDetails.ERROR_CODE_102);
    errorMap.put(ERROR_CODE103, ErrorDetails.ERROR_CODE_103);
    errorMap.put(ERROR_CODE104, ErrorDetails.ERROR_CODE_104);

    System.out.println("errorMap : " + errorMap);
}

/**
 * @param args
 */
public static void main(String[] args) {
    long param = -100;
    StackOverFlowQuestion question = new StackOverFlowQuestion();
    System.out.println("question.errorMap : " + question.errorMap);

    System.out.println("question.errorMap.containskey(param) : "
            + question.errorMap.containsKey(param));
    ErrorDetails errorDetails = question.errorMap.get(param);
    System.out.println("errorDetails : " + errorDetails);

    System.out.println("question.errorMap.containskey((int)param) : "
            + question.errorMap.containsKey((int) param));
    ErrorDetails errorDetailsWithInt = question.errorMap.get((int) param);
    System.out.println("errorDetailsWithInt : " + errorDetailsWithInt);

            int paramInt = -100;
    System.out.println("param == paramInt : " + (param == paramInt));
}
Run Code Online (Sandbox Code Playgroud)

}

================================================== ===============================输出:

StackOverFlowQuestion.StackOverFlowQuestion()

errorMap : {-100=Error code : -100, errorMsg : Error code 100 Desc, canRetry : false, -102=Error code : -102, errorMsg : Error code 102 Desc, canRetry : true, -101=Error code : -101, errorMsg : Error code 101 Desc, canRetry : false, -104=Error code : -104, errorMsg : Error code 104 Desc, canRetry : true, -103=Error code : -103, errorMsg : Error code 103 Desc, canRetry : false}

question.errorMap : {-100=Error code : -100, errorMsg : Error code 100 Desc, canRetry : false, -102=Error code : -102, errorMsg : Error code 102 Desc, canRetry : true, -101=Error code : -101, errorMsg : Error code 101 Desc, canRetry : false, -104=Error code : -104, errorMsg : Error code 104 Desc, canRetry : true, -103=Error code : -103, errorMsg : Error code 103 Desc, canRetry : false}

question.errorMap.containskey(param) : false
errorDetails : null

question.errorMap.containskey((int)param) : true
errorDetailsWithInt : Error code : -100, errorMsg : Error code 100 Desc, canRetry : false

param == paramInt : true
Run Code Online (Sandbox Code Playgroud)

================================================== ===============================

这里有几个我需要澄清的问题

  1. 代码正在编译,即使我将一个long作为参数传递给HashMap的get方法,该方法被声明为只有Integer作为键.我在这里期待编译错误,因为我不知何故觉得这违反了严格的打字.
  2. 当我将包含错误代码的long变量作为参数传递给HashMap()的get方法时,映射返回null.
  3. 当我将相同的long参数向下转换为int并将其传递给哈希映射的get方法时,映射将返回正确的Enum.

我怀疑HashMap.get()方法中的下一行 if (e.hash == hash && ((k = e.key) == key || key.equals(k)))

我不确定int == long是否会失败或者它们相应的包装器是否会失败.我甚至在main方法中添加了一个检查以验证int和long变量的相等性.

我想了解这里的行为.

Jon*_*eet 8

代码正在编译,即使我将一个long作为参数传递给HashMap的get方法,该方法被声明为只有Integer作为键.我在这里期待编译错误,因为我不知何故觉得这违反了严格的打字.

你看看签名了Map.get吗?

V get(Object key)
Run Code Online (Sandbox Code Playgroud)

任何对象都可以用作密钥.关于该设计决策还有其他Stack Overflow问题; 我稍后会找到一个.

当我将包含错误代码的long变量作为参数传递给HashMap()的get方法时,映射返回null.

是的,它会 - 因为它将被装箱到a Long,而a Long不等于a Integer.因此,在地图中找不到该条目.

当我将相同的long参数向下转换为int并将其传递给哈希映射的get方法时,映射将返回正确的Enum.

是的,它会 - 因为它将被装箱到一个Integer,它将等于相应的钥匙.

基本上你被事实所迷惑,你可以比较intlong价值观-这只是编译器会自动提升intlong你; 如果您认为Integer并且Long作为完全独立的类型,并且它们之间没有自动转换,则地图的行为非常有意义.