6
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));
}

}

================================================== =============================== 出力:

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

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

ここに私が明確にする必要があるいくつかの質問があります

  1. キーとして Integer のみを持つように宣言されている HashMap の get メソッドにパラメーターとして long を渡しても、コードはコンパイルされます。これは厳密な型付けに違反していると感じているため、ここでコンパイルエラーが発生することを期待していました。
  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 が失敗するか、対応するラッパーが失敗するかはわかりません。メイン メソッドにチェックを追加して、int 変数と long 変数が等しいことを確認しました。

ここでの動作を理解したいと思います。

4

4 に答える 4

9

キーとして Integer のみを持つように宣言されている HashMap の get メソッドにパラメーターとして long を渡しても、コードはコンパイルされます。これは厳密な型付けに違反していると感じているため、ここでコンパイルエラーが発生することを期待していました。

のサインを見ましたMap.getか?

V get(Object key)

任意のオブジェクトをキーとして使用できます。その設計上の決定については、他にもスタック オーバーフローに関する質問があります。後で見つけます。

エラー コードを含む long 変数をパラメーターとして HashMap() の get メソッドに渡すと、マップは null を返します。

はい。Long_ Long_ Integerそのため、エントリはマップに見つかりません。

同じ long パラメータを int にダウンキャストしてハッシュ マップの get メソッドに渡すと、マップは適切な Enum を返します。

Integerはい、そうです。これは、適切なキーに等しい にボックス化されるためです。

基本的に、比較して評価できるという事実にだまされています。これは、コンパイラが自動的にプロモートするだけです。とを完全に別個の型と考え、それらの間で自動変換を行わない場合、マップの動作は完全に理にかなっています。intlongintlongIntegerLong

于 2013-02-05T08:20:49.630 に答える
1

1.) キーとして Integer のみを持つように宣言されている HashMap の get メソッドにパラメーターとして long を渡しても、コードはコンパイルされます。これは厳密な型付けに違反していると感じているため、ここでコンパイルエラーが発生することを期待していました。

ここにコンパイル エラーはありません。ジェネリック型によって制限されたパラメーターを持つ Map の唯一のメソッドはputメソッドです。getcontainsKey受け入れますObject

2.) エラー コードを含む long 変数をパラメーターとして HashMap() の get メソッドに渡すと、マップは null を返します。

呼び出すget(param)と、 に変換されget(new Long(param))ます。Integerしたがって、引数がキーと等しくなることはありません

3.) 同じ long パラメータを int にダウンキャストし、それをハッシュ マップの get メソッドに渡すと、マップは適切な Enum を返します。

呼び出すget((int)param)と、 に変換されget(new Integer((int)param))ます。したがって、引数の型は正しくなり、結果は期待したものになります。

于 2013-02-05T08:30:23.670 に答える
0

longをintにキャストする必要があります。

于 2013-02-05T08:22:58.170 に答える
0

簡単な答えは次のとおりです: Integer == Long は常に等しくなりません ([Long].equal([Integer]) == false) また、 Long.hashCode() == Integer.hashCode() が同じ結果を返すこともありません。

その答えを詳しく説明するには:

オートボクシングにより、long は Long に変換され、Map 内の同じ hashCode を持つ他のオブジェクトと比較されます。HashCode の特定の実装は、Long と Integer で同じであってはならないため、既に失敗している可能性があります。equals チェックが行われているにもかかわらず、hashCode が同じである場合、すべての equals メソッドと同様に、「[Type] のインスタンスであるか」をチェックするか、false を返すため、これは失敗します。Long と Integer を比較するすべてのケースで失敗します。

したがって、あなたのケースで行う必要があるのは、 long を int にキャストするか、まったく同じ(オートボクシング)を行う Integer.valueOf((int)param) を実行することだけです。

于 2013-02-05T08:29:52.863 に答える