【问题标题】:Is constructor of private inner class also private?私有内部类的构造函数也是私有的吗?
【发布时间】:2016-01-08 14:07:32
【问题描述】:

我正在重构一个越来越大的 android 项目。运行 lint 给了我 JSME 问题 外部和内部类之间的私有成员访问权限。考虑以下示例

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

    private class Inner {}
}

我得到了信息

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

应用问题解决方案将源更改为

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

    private class Inner {
        Inner() {}
    }
}

我现在有点困惑。到目前为止,我认为这个例子相当于

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

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

在这种情况下我错了还是皮棉问题?

【问题讨论】:

  • 当你将一个类声明为私有时,属于该类的所有内容都将变为私有
  • @cricket_007 遗憾的是没有。它不包括 lint 抱怨的部分。
  • 那我不太明白这个问题。拥有public 构造函数与包级(无访问修饰符)构造函数并不重要,因为类本身是private。例如。 Outer 之外的任何课程都不能访问Outer.Inner。 lint 消息似乎在说,如果没有比private 限制更少的构造函数,你就不能说new Inner()
  • 看看这个答案。 stackoverflow.com/a/15287730/2308683

标签: java android android-studio inner-classes android-lint


【解决方案1】:

Section 8.8.9 of the Java language specification, "Default constructor" 说:

在一个类类型中,如果该类被声明为public,那么默认 构造函数被隐式赋予访问修饰符 public(第 6.6 节);如果 该类被声明为受保护,则默认构造函数为 隐含地给定访问修饰符 protected(第 6.6 节);如果班级是 声明为私有,则默认构造函数被隐式赋予 访问修饰符私有(§6.6);否则,默认构造函数有 没有访问修饰符隐含的默认访问。

【讨论】:

    【解决方案2】:

    您的理解有误,但 linter 并不是特别清楚,并且该建议可能与 Android(不是 J2ME)无关。

    正如 David 所解释的,内部类的隐式默认构造函数与类本身具有相同的访问修饰符,但私有成员可以在同一个编译单元(Java 文件)中访问。没有语言理由避免使用私有构造函数。

    但是,在内部,由于类被编译成单独的输出文件,编译器必须创建合成适配器方法来为类提供对私有成员的访问。这些方法的运行时缺点与桌面应用程序无关,但对于像 J2ME 这样狭窄的应用程序,通过使成员可直接访问(使用包范围)来消除差异可能是值得的。

    Android 对类文件执行重要的后处理,Android 设备不像 J2ME 设备那样受限。除非您正在编写针对两个平台的代码,否则我会更改 lint 配置。

    【讨论】:

      猜你喜欢
      • 2011-09-13
      • 1970-01-01
      • 2017-07-13
      • 2016-08-16
      • 2019-10-16
      相关资源
      最近更新 更多