java 在oops概念中类是否占用内存

p8h8hvxi  于 2023-01-15  发布在  Java
关注(0)|答案(1)|浏览(141)

根据Java中的定义,如果类不占用内存,只是充当一个模板,那么为什么我们要在类的花括号内创建对象(主方法)呢?这是否意味着现在类也占用内存,因为它内部存在对象?
尝试理解类的定义

wvt8vs2t

wvt8vs2t1#

这里有三个概念需要分开:类、示例和堆栈。

class SomeClass {
  static int staticValue = 0;

  /* non-static */ int instanceValue = 0;

  int someMethod() {
    int stackValue = 42;
    SomeClass instance = new SomeClass();
    // ...
  }
}

类充当模板,是的。在Java以外的一些语言中,类不占用自己的内存:它仅仅描述了类示例的内存布局。对于一个OOP概念的初学者来说,你可以认为这是正确的。
在Java中,这并不完全正确,原因有三:

  1. SomeClass有一个对象示例,可通过SomeClass.class访问,它确实占用内存,这个示例允许您查找有关类本身的信息,有时称为“反射”。
    1.静态字段staticValue在SomeClass的所有示例之间共享,因此在某种意义上,该类占用少量内存来包含此共享值。
  2. SomeClass包含像someMethod这样的方法,并且代码必须在内存中才能运行。如果你愿意考虑代码需要内存,并且代码与类相关联,那么类消耗内存。然而,谈论OOP概念的人通常不会谈论代码本身消耗的内存。
    这可以与类SomeClass的 instances 相比较,对于您创建的每个示例,它至少包含一个单独的值instanceValue。示例没有自己的代码,并且(在Java中)包含一个对其Class示例的引用,可以通过getClass()访问。
    最后,方法someMethod和您的main示例确实使用了消耗内存的引用和局部变量,但是在与示例或类不同的地方,这个地方被称为“堆栈”,部分原因是当您调用方法和那些调用进一步方法时,堆栈像table上的一堆纸一样增长,这意味着可能同时存在stackValue的多个副本,每次调用someMethod时都有一个。stackValue的每个值在其对应的someMethod调用返回时都被丢弃。这些值没有直接绑定到类或示例,除此之外,它们是可能被认为与上面#3中的类相关的代码。忽略编译代码本身消耗的内存,instance不会导致SomeClass或其示例以与OOP相关的方式消耗更多内存。
    (用new创建的示例不是“栈”的一部分,而是“堆”的一部分,在这个解释层次上,并且包括SomeClass.class示例和SomeClass的任何示例。一些语言需要仔细管理堆的存储器,但是Java通过一个叫做 * 垃圾收集 * 的过程来管理它,但是像stackValue和名为instance的 * 引用 * 这样的原语保留在堆栈上。)

相关问题