質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.02%

javaのMapの記述の仕方について

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 4,317

a0841_1974

score 23

いつもお世話になっております。
Javaの記述の仕方で分からない事があります。
ご存知の方がいらっしゃれば教えて頂けますでしょうか。

【ご質問】
以下のプログラムを記述すると
☆1で警告が表示されます。
警告を解消する為には、どのように修正すればよいのでしょうか。

JAVAのバージョンは1.8です。

public Map<Object,Object> getTantousya(){
    String cacheKey = "tantousya:N";
    Map<Object,Object> result = (Map)masterMap.get(cacheKey); ☆1
    if(result == null){
        result = key_value_service.getTantousya();
        masterMap.put(cacheKey, result);
    }
    return result;
}

(警告の内容)
☆1
型の安全性: 型 Map の式は、未検査の型変換を使用して Map<Object,Object> に準拠するようにする必要があります

(補足)
1.masterMapは、以下の様に宣言しております。

private final HashMap<String,Object> masterMap = new HashMap<>();

  

2.key_value_service.getTantousya()、以下の様に宣言しております。

public Map<Object,Object> getTantousya()

 
3.☆1の箇所を

 Map<Object,Object> result = (Map<Object,Object>)masterMap.get(cacheKey);

 
に、変更すると、以下の警告が表示されます。

この行に複数マーカーがあります

  • Map は raw 型です。総称型 Map<K,V> への参照は、パラメーター化する必要があります
  • 型の安全性: Object から Map<Object,Object> への未検査キャスト

以上です。
よろしくお願いいたします。

(追記)
Map<Object, Object>には、
以下のどちらかの戻り値を設定いたします。

public Map<Object,Object> getQuerykeyValue(Integer renban){
  List<KeyValue> list = keyValueMapper.querykeyValue(renban); 
  Map<Object,Object> result = new HashMap<>();
  for(int i=0;i<list.size();i++){
    KeyValue keyvalue = (KeyValue)list.get(i);
    result.put(keyvalue.getKey(), keyvalue.getValue());
  }
  return result;
}

public Map<Object,Object> getQuerykeyValueInteger(Integer renban){
  List<KeyValue> list = keyValueMapper.querykeyValueInteger(renban);
  Map<Object,Object> result = new HashMap<>();
  for(int i=0;i<list.size();i++){
    KeyValue keyvalue = (KeyValue)list.get(i);
    result.put(keyvalue.getKey(), keyvalue.getValue());
  }
  return result;
}

【KeyValue】
public class KeyValue implements Serializable {
  static final long serialVersionUID = 1L;
  private Object key;
  private Object value;
  getter/setter
}

【querykeyValueで実施するSQL】
<select id="querykeyValue" resultType="KeyValue">
  SELECT key AS "key",
         value AS "value"
    FROM key_value_tbl
   WHERE renban = #{renban}
   ORDER BY sort_no
</select>


【querykeyValueIntegerで実施するSQL】
<resultMap id="ResultMapInteger" type="KeyValue">
  <result property="key" column="key" javaType="Integer" />
  <result property="value" column="value" javaType="String" />
</resultMap>
<select id="querykeyValueInteger" resultMap="ResultMapInteger">
  SELECT key AS "key",
         value AS "value"
    FROM key_value_tbl
   WHERE renban = #{renban}
   ORDER BY sort_no
</select>

【key_value_tblテーブルの型】
key   VARCHAR
value VARCHAR
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • swordone

    2018/04/04 12:34 編集

    masterMapの値にはMap<Object, Object>型以外のモノが入っていますか?(masterMapの型をMap<String, Map<Object, Object>>として問題がないか?)

    キャンセル

  • a0841_1974

    2018/04/04 13:00

    ご連絡ありがとうございます。masterMapの値にはMap<Object, Object>型以外のものは入りません。

    キャンセル

回答 3

checkベストアンサー

0

こういう警告ですね?(コンパイルオプション-Xlint:uncheckedを指定してます)

T.java:6: 警告:[unchecked] 無検査キャスト
    Map<Object,Object> result = (Map<Object, Object>)masterMap.get(cacheKey); //☆1
                                                                  ^
  期待値: Map<Object,Object>
  検出値:    Object


これはObjectをMap<Object, Object>へダウンキャストしているためですが、コンパイラーはこのダウンキャストが安全かどうか判断できません。"tantousya:N"というキーの値が必ずMap<Object,Object>になっているはずというのは(キャストが問題ないというのは)論理全体を見渡せる人間のみが判断できることです。

この警告を消すには「論理的にこのダウンキャストが問題ないと判断してるので警告は不要ですよ」とコンパイラーに伝える必要があり、それは@SuppressWarningsアノテーションを用いるとできます。

public Map<Object,Object> getTantousya(){
  String cacheKey = "tantousya:N";
  @SuppressWarnings("unchecked") // これ
  Map<Object,Object> result = (Map<Object, Object>)masterMap.get(cacheKey); //☆1
  if (result == null) {
    result = key_value_service.getTantousya();
    masterMap.put(cacheKey, result);
  }
  return result;
}


追記:ちなみに型引数の指定なしでMap型の値をMap<Object,Object>型の変数へ代入するのは警告の対象になりますが、それは型引数も含めてきっちりキャストする必要があります。上のコードではその点も修正しています。

参考:
https://docs.oracle.com/javase/jp/8/docs/api/java/lang/SuppressWarnings.html

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/04/06 00:06

    ご回答ありがとうございます。
    KeyValueは汎用クラスの目的で作成しております。
    今のところKeyにはInteger,String,Longが来ることを想定しております。

    キャンセル

  • 2018/04/06 00:47

    04/05 18:51にコメントしましたように、KeyValueクラスの定義のしかたによってキーをObject型にせずにInteger,String,Longそれぞれとして扱うこともできますが・・・
    本質問の主題からはなれてしまいますし、コメント欄で話せるほど単純な話題でもないのでキーワードだけコメントしておきますと「generics, generic method」あたりになると思います。機会があればその辺りを掘り下げてみるとよいかと思います。

    キャンセル

  • 2018/04/06 10:19

    ご回答ありがとうございます。
    ジェネリクスについて詳しく分かっていないので、調べてみます。
    ありがとうございます。

    キャンセル

0

こうやな・w・

public static void main(String[] args) {
    Map<Object, Object> omap = new HashMap<>();
    omap.put("a", "9");
    Object map = omap;
    Map<? extends Object, ? extends Object> xmap = (Map<?, ?>) map;
    System.out.println(xmap.get("a"));
}

 map型じゃないケースを想定するとこうなる「

public static void main(String[] args) {
    Map<Object, Object> omap = new HashMap<>();
    omap.put("a", "9");

    // Map<Object,Object>#get を課程
    Object map = omap;

    // 以下 説明ソース
    Map<? extends Object, ? extends Object> xmap;
    if (map instanceof Map) {
        // 設定時
        xmap = (Map<?, ?>) map;
    } else {
        // 未設定時(任意の別のマップを設定するなりしてください)
        xmap = omap;
    }
    System.out.println(xmap);

}

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/04/04 13:52

    ご連絡ありがとうございます。
    ご連絡頂きました方法で出来ましたが、以下の場合はどのように記述したらよいのでしょうか。
    public Map<Object,Object> getTantousyaWithNULL(){
    // キャッシュキー名を取得するデータ毎に設定する。
    String cacheKey = "tantousya:NULL";
    Map result = (Map)masterMap.get(cacheKey);
    if(result == null){
    result = new HashMap();
    result.put((Object)new Integer(-1), (Object)"(指定なし)");
    result.putAll(key_value_service.getTantousya());
    masterMap.put(cacheKey, result);
    }
    return result;
    }

    キャンセル

0

多少割愛しましたが、警告はなくなりました。

    public Map<Object, Object> getTantousya() {
        String cacheKey = "tantousya:N";
        Map<Object, Object> masterMap = new HashMap<>();
        Map<?, ?> result = (Map<?, ?>) masterMap.get(cacheKey);
        return new HashMap<>(result);
    }

ご参考までに
List<Object>とList<?>の違い

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/04/04 13:51

    ご連絡ありがとうございます。
    ご連絡頂きました方法で出来ましたが、以下の場合はどのように記述したらよいのでしょうか。
    public Map<Object,Object> getTantousyaWithNULL(){
    // キャッシュキー名を取得するデータ毎に設定する。
    String cacheKey = "tantousya:NULL";
    Map result = (Map)masterMap.get(cacheKey);
    if(result == null){
    result = new HashMap();
    result.put((Object)new Integer(-1), (Object)"(指定なし)");
    result.putAll(key_value_service.getTantousya());
    masterMap.put(cacheKey, result);
    }
    return result;
    }

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.02%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る