par*_*ver 6 java static static-classes java-8
我在 java 中使用静态嵌套类用于特定用例。下面显示了相同的最小示例:
public class Foo {
static int fooInner = getInner(); // CASE 1
private static class StaticFoo {
int fooInner = getInner(); // CASE 2
public int useFooInner(){
System.out.println(fooInner);
//do something
}
}
}
Run Code Online (Sandbox Code Playgroud)
问题是案例 1 中的内存分配与案例 2 中的内存分配有何不同?或者是一样的?如果我也将 case 2 变量设为静态会怎样。内存使用会有所不同吗?
注意:请不要提及会发生阴影。虽然我已经将两个变量都放在那里,但它是一个“OR”案例,这就是“CASE”的原因。
PS:感觉内存使用量应该是一样的。由于嵌套类是静态的,因此不会为每个对象创建它,因此实例变量fooInner (案例 2)也将只创建一次。因此, getInner() 函数将只运行一次。但这只是抽象层面+直觉。更具描述性的答案将不胜感激!
他们是不同的。
从内存分配的角度来看,静态内部类与顶级类没有什么不同。您将被编译为一个在运行时本质上独立于其父类的StaticFoo类 ( )。Foo$StaticFoo.class在编译时,会对私有成员进行访问检查。
因此,在情况 1 中,类中有一个静态字段。它将被分配为Foo.class堆上对象的字段。每个 ClassLoader 只会有一个实例来加载 Foo 类,这通常意味着整个 JVM 只有一个共享实例。
在情况 2 中,类中有一个实例字段Foo$StaticFoo。在堆上,将为创建的每个 StaticFoo 实例分配空间(并分配一个值)。创建的每个 StaticFoo 将访问该字段自己的实例,并且由于它不是final,因此每个实例的值都可以独立更改。
如果改为StaticFoo.fooInner,static则与情况 1 完全相同。
注意:以上仅适用于 Java 8 及更高版本。对于早期的 JVM,每种情况下分配的内存量仍然与上面的描述相符,但静态变量以及每个 ClassLoader 的单例也存储在不同的内存池中:PermGen Space 而不是主堆。有关更多详细信息,请参阅此答案。
| 归档时间: |
|
| 查看次数: |
158 次 |
| 最近记录: |