为什么java.util.ArrayList包中的数据数组是私有的?

为什么java.util.ArrayList包中的数据数组是私有的?,java,arraylist,visibility,inner-classes,Java,Arraylist,Visibility,Inner Classes,在java.util.ArrayList类中,列表元素的对象数组定义为包私有: transient Object[] elementData; // non-private to simplify nested class access 注释指出,该字段不是私有字段的原因是在嵌套类中更容易访问。然而,嵌套类可以很好地访问封闭类的私有数据。那么为什么elementData不是私有的呢?后台是否发生了什么事情(例如,在编译时)?当您从嵌套类访问私有字段时,编译器实际上会生成一个可见的包,然后将其用

java.util.ArrayList
类中,列表元素的对象数组定义为包私有:

transient Object[] elementData; // non-private to simplify nested class access

注释指出,该字段不是私有字段的原因是在嵌套类中更容易访问。然而,嵌套类可以很好地访问封闭类的私有数据。那么为什么
elementData
不是私有的呢?后台是否发生了什么事情(例如,在编译时)?

当您从嵌套类访问私有字段时,编译器实际上会生成一个可见的包,然后将其用于访问。它不能直接访问私有成员,因此为了避免这种间接操作,您可以改为使成员包可见

这里有更多的细节

但是,嵌套类可以访问封闭类的私有数据 很好

这对于
静态的嵌套类不适用

至少类
ArrayList.SubList
static
并访问
elementData

另请参见此处:

正如@tevemadar向我表明的那样,我在这里所说的完全错误。 这是@tevemadar提供的一个工作示例:

public class Test
{
    private int a = 0;

    public static void main(String[] args)
    {
        new Inner().doTest(new Test());
    }

    static class Inner
    {
        void doTest(Test t)
        {
            System.out.println(t.a);
        }
    }
}

这一评论已经过时。随着的引入,编译器将不再创建语法方法;这是在jdk-11中介绍的


在此更改之前,像
ArrayList
这样的高度使用的结构的问题是调用堆栈中的另一种方法(用于访问
private
字段)在关键路径中可能会有很高的成本。为了避免调用另一个方法,您可以在不使用
private

的情况下声明字段,这可能是
static
的一个约束/特性。静态内部类不能直接访问外部对象的字段,因为没有外部对象(一般来说,
static
things)。这就是为什么这篇文章提到了对象引用的需要。是的,这是静态的一个特性。但是ArrayList.Sublist不能访问dataElement,因为它是一个静态类。因此,它通过一个称为root的ArrrayList引用来访问它。这只在elementData是包私有的情况下起作用。最初的问题是,为什么这个字段是包保护的而不是私有的。这只有在elementData是包私有的情况下才有效。-不,它也可以与显式的
private
一起工作。试试这个:
公共类测试{private int a=0;公共静态void main(String[]args){new internal().doTest(new Test());}静态类内部{void doTest(Test t){System.out.println(t.a);};}
你说得对。谢谢你这么顽强。这帮助我摆脱了错误的假设。
ArrayList
和其他类的代码似乎没有更新以利用nest mate功能。对于JDK邮件列表,建议进行此类更新。