根据Java中的定义,如果类不占用内存,只是充当一个模板,那么为什么我们要在类的花括号内创建对象(主方法)呢?这是否意味着现在类也占用内存,因为它内部存在对象?尝试理解类的定义
wvt8vs2t1#
这里有三个概念需要分开:类、示例和堆栈。
class SomeClass { static int staticValue = 0; /* non-static */ int instanceValue = 0; int someMethod() { int stackValue = 42; SomeClass instance = new SomeClass(); // ... } }
类充当模板,是的。在Java以外的一些语言中,类不占用自己的内存:它仅仅描述了类示例的内存布局。对于一个OOP概念的初学者来说,你可以认为这是正确的。在Java中,这并不完全正确,原因有三:
SomeClass.class
staticValue
someMethod
instanceValue
getClass()
main
stackValue
instance
new
1条答案
按热度按时间wvt8vs2t1#
这里有三个概念需要分开:类、示例和堆栈。
类充当模板,是的。在Java以外的一些语言中,类不占用自己的内存:它仅仅描述了类示例的内存布局。对于一个OOP概念的初学者来说,你可以认为这是正确的。
在Java中,这并不完全正确,原因有三:
SomeClass.class
访问,它确实占用内存,这个示例允许您查找有关类本身的信息,有时称为“反射”。1.静态字段
staticValue
在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
的 * 引用 * 这样的原语保留在堆栈上。)