当前位置: 首页 > 面试题库 >

Java私有内部类是否有性能开销?

范俊逸
2023-03-14
问题内容

当我拥有带有私有方法或字段的内部类时,编译器必须创建受程序包保护的合成访问器方法,以允许外部类访问那些私有元素(反之亦然)。

为了避免这种情况,我通常将所有字段和方法以及构造函数设置为受包装保护,而不是私有的。

但是类本身的可见性如何?有开销吗

 private static class A {
      A(){}
 }

 static class A {
      A(){}
 }

请注意,在这两种情况下,构造函数都受到程序包保护,还是使类私有更改了?


问题答案:

您是否尝试过编译并比较字节码?这是我的结果。对于:

public class Example {
  public static void main(String[] args) {
    System.out.println("Hello world!");
  }
  private static class A {
    A(){}
  }
}

上面产生了以下* .class文件:

-rw-r--r--    1 michaelsafyan  staff   238 Feb 10 00:11 Example$A.class
-rw-r--r--    1 michaelsafyan  staff   474 Feb 10 00:11 Example.class

现在,如果我移动类文件,删除private修饰符,然后重新编译,则会得到:

 -rw-r--r--    1 michaelsafyan  staff   238 Feb 10 00:15 Example$A.class
 -rw-r--r--    1 michaelsafyan  staff   474 Feb 10 00:15 Example.class

如果查看类文件上的VM
Spec
,您会发现有一个用于指定访问修饰符的大小固定的位字段,因此生成的文件大小相同也就不足为奇了。

简而言之,您的访问修饰符不会影响生成的字节码的大小(也不会影响性能)。您应该使用最有意义的访问修饰符。

我还应该补充一点,如果将内部类从声明更改static为未声明static,则会有细微的差别,因为这意味着引用外部类的附加字段。与声明内部类相比static,这将占用更多的内存,但是您会为此疯狂地进行优化(static在有意义的地方以及需要它为非静态的地方使用,使其成为非静态的,但是不要只为了在这里或那里保存内存指针而使设计复杂化)。



 类似资料:
  • 问题内容: 在我经历1000 s 之后,可能不需要 是否有 任何情况下, 该下降从将使在差异 封装 (或 使用 例如,通过外)?还考虑思考 如果 不 建议将其删除或使其与编码风格保持一致? 我说 没有 和 下降 ,但不知道真的。 编辑: 刚意识到 我 的方式肯定是错误的-至少对于的 字段 -声明这些字段为私有字段,然后在外部类中使用它们- 因为这会在字节码中生成( “ synthetic” )访问

  • 问题内容: 在C#中,您可以将一个类标记为,以便只能从同一包中对其进行访问。Java有什么类似的东西吗? 问题答案: 您可以通过从类的声明中省略安全修饰符(公共,私有)来创建程序包专用类。

  • 问题内容: 如果我有一个包私有的Java类(用“ class”声明,而不是“ public class”),那么将内部方法声明为public或protected或package- private确实没有区别,对吗?那么我应该使用哪个,或者什么时候该使用呢?我有点困惑。 问题答案: 如果我有一个包私有的Java类(用“ class”声明,而不是“ public class”),那么将内部方法声明为p

  • 我正在重构一个越来越大的android项目。运行lint使我能够在外部类和内部类之间访问JSME问题私有成员。考虑下面的例子 我得到消息了 应用问题解决方案会将源更改为 我现在有点困惑。直到现在,我还以为这个例子相当于 在这种情况下,我错了吗?还是这是棉绒的问题?

  • 我想使用Powermock(基于EasyMock)模拟私有静态内部类。这不是来自生产代码,这只是一个是否可能的问题。我很确定这是一个糟糕的设计,但这是我为科学而努力的东西。 假设我们有一个具有静态私有内部类的类: IExpectationSetters中的andReturn(capture)不能应用于(java.lang.Object)  私人静态内部阶级的嘲笑甚至可能吗?我还没有在SO上找到一个

  • 问题内容: 如果仍然无法在包含类的外部访问它,则用Java声明一个私有内部类的成员的原因是什么?可以吗 问题答案: 如果该类没有扩展任何类或实现任何接口,那么我认为这是无稽之谈,因为没有其他类可以访问它的任何实例。 但是,如果它扩展或实现了任何其他非私有类或接口,则是有意义的。一个例子: