简体   繁体   English

私有内部类的构造函数也是私有的吗?

[英]Is constructor of private inner class also private?

I'm refactoring an android project which is getting to big. 我正在重构一个正在变大的android项目。 Running lint gives me the JSME issue Private member access between outer and inner classes . 运行lint为我提供了JSME问题 外部和内部类之间的私有成员访问 Considering the following example 考虑以下示例

public class Outer {
    private Inner mInner = new Inner();

    private class Inner {}
}

I get the information 我得到了这些信息

Name
   private field Inner mInner

Location
   class Outer (default package)

Problem synopsis
   Access to private member of class 'Inner' at line 2

Problem resolution
   Make 'Inner' constructor package-local

Applying the problem resolution changes the source to 应用问题解决方案会将源更改为

public class Outer {
    private Inner mInner = new Inner();

    private class Inner {
        Inner() {}
    }
}

I'm a little confused at the moment. 我此刻有点困惑。 Until now I thought the example would be equivalent to 到现在为止,我认为这个例子相当于

public class Outer {
    private Inner mInner = new Inner();

    private class Inner {
        public Inner() {}
    }
}

Am I wrong in this case or is it an issue of lint? 在这种情况下我错了还是皮棉问题?

Section 8.8.9 of the Java language specification, "Default constructor" says: Java语言规范的第8.8.9节“默认构造函数”说:

In a class type, if the class is declared public, then the default constructor is implicitly given the access modifier public (§6.6); 在类类型中,如果类被声明为public,则默认构造函数被隐式赋予访问修饰符public(§6.6); if the class is declared protected, then the default constructor is implicitly given the access modifier protected (§6.6); 如果该类被声明为protected,则默认构造函数被隐式赋予访问修饰符protected(§6.6); if the class is declared private, then the default constructor is implicitly given the access modifier private (§6.6); 如果该类被声明为private,则默认构造函数被隐式赋予访问修饰符private(§6.6); otherwise, the default constructor has the default access implied by no access modifier. 否则,默认构造函数具有无访问修饰符隐含的默认访问权限。

You're wrong in your understanding, but the linter is not being particularly clear, and the advice probably isn't relevant for Android (which isn't J2ME). 你的理解是错的,但是linter并不是特别清楚,而且建议可能与Android(不是J2ME)无关。

As David explained, the inner class's implicit default constructor has the same access modifier as the class itself, but private members are accessible within the same compilation unit (Java file). 正如David解释的那样,内部类的隐式默认构造函数具有与类本身相同的访问修饰符,但私有成员可在同一编译单元(Java文件)中访问。 There's no language reason to avoid the private constructor. 没有语言理由可以避免使用私有构造函数。

However, internally, since the classes are compiled into separate output files, the compiler has to create synthetic adapter methods to provide the classes access to the private members. 但是,在内部,由于类被编译为单独的输出文件,因此编译器必须创建合成适配器方法以提供对私有成员的类访问。 The runtime disadvantage of these methods is irrelevant for desktop applications, but for something as cramped as J2ME, the difference might be worth eliminating by making the member accessible directly (using package scope). 这些方法的运行时缺点与桌面应用程序无关,但对于像J2ME这样狭窄的东西,可以通过直接访问成员(使用包范围)来消除差异。

Android performs significant post-processing on the class files, and Android devices are not nearly as constrained as J2ME devices. Android对类文件执行重要的后处理,而Android设备几乎不像J2ME设备那样受限制。 Unless you're writing code to target both platforms, I'd change the lint configuration. 除非您编写代码来定位两个平台,否则我会更改lint配置。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM