【问题标题】:Why is the data array in java.util.ArrayList package-private?为什么 java.util.ArrayList 包中的数据数组是私有的?
【发布时间】:2021-07-22 12:55:25
【问题描述】:

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

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

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

【问题讨论】:

    标签: java arraylist visibility inner-classes


    【解决方案1】:

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

    这里是an answer,了解更多详情。

    【解决方案2】:

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

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

    【讨论】:

    • ArrayList 和其他类的代码似乎没有更新以利用嵌套配合功能。 JDK 邮件列表中的This mail 建议进行此类更新。
    【解决方案3】:

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

    这不适用于static 的嵌套类。

    至少ArrayList.SubList 类是static 并访问elementData

    另见此处: https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html

    正如@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);
            }
        }
    }
    

    【讨论】:

    • 这可能是static 的约束/功能@ 您可能的意思。静态内部类不能直接访问外部对象的字段,因为没有外部对象(一般static事物)。这就是为什么这篇文章写到需要一个对象引用。
    • 是的,这是静态的一个特性。但是 ArrayList.Sublist 不能访问 dataElement,因为它是一个静态类。所以它通过 ArrayList 的引用访问它,称为 root。这只有在 elementData 是包私有的情况下才有效。最初的问题是,为什么该字段是包保护的而不是私有的。
    • 只有当 elementData 是包私有时才有效。 - 不,它也适用于明确的private。试试这个: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);}};}
    • 你是对的。谢谢你这么顽强。这帮助我摆脱了错误的假设。
    猜你喜欢
    • 2014-04-06
    • 2012-02-26
    • 2010-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-06
    • 2012-02-28
    • 1970-01-01
    相关资源
    最近更新 更多