You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中entrySet相关疑问:为何调用getKey()的代码可正常运行?

问题背景

以下是一段Java代码:

// Using entrySet() to get the entry's of the map
// m is previously created Map.
Set<Map.Entry<String,Integer>> s = m.entrySet();
for (Map.Entry<String, Integer> it: s) {
    String str = it.getKey();
}

已知:

  • Map.Entry仅为一个接口。
  • 接口本身并没有getKey();方法的实现。

请问为何上述代码能够正常运行?编译器是如何知晓getKey()方法的行为的?


问题解答

这其实是Java多态特性和集合框架设计逻辑的结合,咱们一步步拆解清楚:

  • entrySet()返回的是接口的具体实现实例
    你代码里的m肯定是某个Map接口具体实现类的对象(比如HashMap、TreeMap这些常用实现)。这些Map实现类内部都自带了Map.Entry接口的具体实现类——比如HashMap里的Node内部类,它不仅实现了Map.Entry接口,还完整写好了getKey()、getValue()等方法的执行逻辑。

  • 编译器只关心静态类型的方法声明
    编译阶段,编译器看到变量it的静态类型是Map.Entry<String, Integer>,它只会去校验Map.Entry接口里有没有声明getKey()方法——而Map.Entry接口本身就明确定义了K getKey();这个抽象方法,所以编译器会判定这段代码合法,不会抛出编译错误。

  • 运行时才会调用实际对象的实现逻辑
    到了程序运行阶段,JVM会根据it指向的实际对象类型(比如HashMap$Node),调用该对象中已经实现好的getKey()方法。这就是多态的核心:接口负责定义规范,具体实现类提供执行逻辑,编译看接口、运行看实际对象。

举个直观的例子,HashMap源码里的Node类(简化版)就是这么实现的:

static class Node<K,V> implements Map.Entry<K,V> {
    final K key;
    V value;
    Node<K,V> next;
    int hash;

    // 构造方法等...

    @Override
    public K getKey() {
        return key;
    }

    @Override
    public V getValue() {
        return value;
    }
}

当你调用HashMap的entrySet()时,返回的集合里全是这种Node对象,它们已经把getKey()的实现逻辑写死了,所以运行时调用完全没问题。

内容的提问来源于stack exchange,提问作者Lin Paul

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:07:15