JDK源码疑问:未通过new实例化的对象为何可调用非静态方法?
Great question! Let's clear up this confusion step by step.
First off, the key point here is: the SubList object you're using has indeed been instantiated with new—you just don't see that line of code directly in the snippet you shared.
1. 实例化过程隐藏在AbstractList.subList()方法内部
如果你查看AbstractList的源码,它的subList()方法其实在内部创建并返回了一个SubList实例。代码大概是这样的:
public List<E> subList(int fromIndex, int toIndex) { return (this instanceof RandomAccess ? new RandomAccessSubList<>(this, fromIndex, toIndex) : new SubList<>(this, fromIndex, toIndex)); }
当你对一个AbstractList(比如继承它的ArrayList)调用list.subList(from, to)时,这个方法会用SubList的构造函数创建新对象,然后返回给你。这就是为什么你能在返回结果上调用非静态方法——你操作的是一个完全实例化的对象。
2. SubList的构造函数是包访问权限
注意你提供的代码片段里,SubList的构造函数没有public修饰符:
SubList(AbstractList
list, int fromIndex, int toIndex) { ... }
这让它成为包私有方法,意味着只有同一个包(java.util)里的类可以直接调用它。AbstractList和SubList在同一个包下,所以它能直接实例化SubList,而外部代码没法直接用new SubList(...)创建实例。
3. 关于非静态方法的小提醒
非静态方法必须依赖实例才能调用,这是没有例外的。你产生疑问只是因为实例化的过程被封装在subList()方法里,没有在你使用SubList的地方显式写出来而已。
内容的提问来源于stack exchange,提问作者haolong li

