为什么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邮件列表,建议进行此类更新。