继承AbstractList的类中未调用的方法为何自动执行?
为什么AbstractList子类中未主动调用的get/size方法会被触发?
先贴出你的代码参考:
public class OuterClass { static class NestedClass extends AbstractList<List<Integer>> { void add(/* parameters here */) { // note this method is not declared public // print here does NOT appear in output // implementation details here } public int size() { // print here appears in output // implementation details here } public List<Integer> get(int index) { // print here appears in output // implementation details here } } public static List<List<Integer>> method(/* parameters here */) { NestedClass nc = new NestedClass(); nc.add(..); } }
你遇到的情况,核心原因是你的NestedClass实例被其他代码间接调用了size()和get()——哪怕你自己没写nc.get()或nc.size()这样的主动调用。
AbstractList作为Java集合框架的核心类,它的很多默认实现(比如父类的toString()、contains(),或者迭代器相关逻辑)都会依赖size()和get()来完成功能。举几个最常见的触发场景:
- 如果你的
method()方法最后返回了这个NestedClass实例,而调用method()的地方执行了System.out.println(result),那AbstractList的toString()方法会自动遍历所有元素:先调用size()获取总数量,再循环调用get()取出每个元素拼接成字符串。 - 要是用for-each循环遍历这个实例:
for (List<Integer> item : nc) { ... },底层迭代器的实现同样会依赖size()和get()。 - 还有可能是你把这个实例传给了集合工具类(比如
Collections.sort()、Collections.min()等),这些方法内部也会调用size()和get()来完成逻辑。
另外提一句:你代码里的add()方法是包访问权限,但AbstractList的add()是public的抽象方法,其实你这个add()并没有重写父类的方法(重写要求权限不低于父类),这可能会导致一些隐藏问题,但和当前size/get被调用的现象无关。
通用疑问:调用子类任意方法会触发重写的抽象方法吗?
答案是绝对不会。调用子类的某个方法,并不会固有地触发所有重写的抽象方法,只有当以下几种情况发生时,这些抽象方法才会被调用:
- 你调用的这个子类方法内部,主动调用了那些抽象方法;
- 你调用的是父类的非抽象方法,而这个父类方法的逻辑里依赖了抽象方法(比如前面提到的
AbstractList.toString()调用size()和get()); - 外部其他代码(比如打印逻辑、集合工具类、第三方库等)主动调用了这些抽象方法。
总结一下:抽象方法只是要求子类必须提供实现,但它们不会凭空执行,只有当某个业务逻辑需要用到它们的功能时,才会被触发调用。
内容的提问来源于stack exchange,提问作者A is for Ambition
相关产品推荐
相关产品推荐

