什么时候静态方法的实例变量在java中获取内存? 在静态方法中创建实例变量(无论是在参数中还是在函数内声明)是完全正确的,但是我想知道什么时候静态方法的实例变量被分配了内存,如果没有创建类的对象?静态方法的Java实例变量
其实我的意思是说静态方法
什么时候静态方法的实例变量在java中获取内存? 在静态方法中创建实例变量(无论是在参数中还是在函数内声明)是完全正确的,但是我想知道什么时候静态方法的实例变量被分配了内存,如果没有创建类的对象?静态方法的Java实例变量
其实我的意思是说静态方法
首先,术语instance variable
是不准确的,我假设你是问关于local variable
为a
和b
在下面的例子如:
void method(int a) {
int b = 3;
}
在Java中,只有原语和引用存储在堆栈,对象在构建时会存储在堆中。一旦范围结束堆栈将被清理,堆被垃圾收集器清理。
下面是一个例子:
public class Main {
static A a = new A();
static void method() {
int b = 2;
C c = new C();
}
}
第一次你的代码是指Main
,类加载器将加载类和初始化所有的静态字段 - 对象new A()
将进入堆。没有更多发生在这里,方法method
可能不存在。
当调用方法method
,它将在堆栈上添加值2
,那么它将这将指向在堆中的对象new C()
堆栈上添加参考c
。
当方法存在时,2
和c
被从堆栈中移除(实际上没有移除,但堆栈的顶部被改变为下面的两个位置,所以这些两个值将被覆盖,只要其他东西进入堆栈),而new C()
将保留在堆中,直到垃圾收集器触发。由于GC可能会检测到没有更多此对象的引用,因此可能会立即收集垃圾。
我认为从技术上讲,JLS从来没有将方法参数称为局部变量,但是在考虑这些参数时没有害处。 –
以下是有关变量类型的JLS:https://docs.oracle.com/javase/specs/jls/se8/html/jls-4.html#jls-4.12.3 – Tom
这很有趣,JLS与所有变种不同教程(包括Oracle教程)以及我们开发人员每天使用的术语。但好点,你们两个。 –
内的局部变量如果您声明一个变量或参数使用静态方法里面,它不是在所有的实例变量。一旦该方法被调用
static void methodTest(int i) {
String s = "Hello";
}
这里s
是一个局部变量,以这种方法它是一个局部变量,它会被初始化。 和i
是函数参数,它也是方法的局部变量
本地变量's'将在调用方法时初始化,而不是在加载类时初始化。 –
在静态方法中没有这样的东西作为实例变量。
如果您指的是参数和局部变量,那么它们将在堆栈上分配(任何创建的对象都像往常一样分配在堆上)。
该类的静态字段将在加载类时初始化。
当构造实例时,类的实例变量将被分配(并可能被初始化)。
你的意思是'stack'而不是'heap'(局部变量)?最后一句中可能是'instance fields',而不是'instance variables'。 –
@JaroslawPawlak关于stack vs堆的好处,谢谢!固定。我已经看到“insatnce fields”和“instance variables”都用于描述相同的内容,所以我选择坚持OP的术语。 [Wikipedia](https://en.wikipedia.org/wiki/Instance_variable)似乎也赞成后者。 [The utlimate judge](http://www.googlefight.com/%22instance+field%22-vs-%22instance+variable%22.php)。 –
静态方法定义的变量仍然是方法范围内的局部变量,就好像非静态方法创建的局部变量一样。然而,问题是,只要类加载器(通常是主类,只在运行时终止时才“卸载”,就像用右手抓住左耳朵一样)没有被卸载并且垃圾集。只有当对象不再被引用时,对象才得到GC'd,并且在静态字段的情况下,由于我描述的行为,即使没有使用它们,它们也有被引用的倾向。因此,在大型应用程序中,内存和资源都是问题,在静态方法中声明任何内容是非常糟糕的想法,因为您很快会用无法收集的LOCAL VARIABLES污染内存。
您不能在方法内声明静态字段。 –
@PaulBoddington不,但保留局部变量的方法即使在执行后仍然被加载,因此其局部变量仍保留在堆栈中。上次我检查时,Java GC只收集卸载的类,而不是方法或字段。 –
*“在静态方法中声明任何内容是非常糟糕的主意,因为你很快就会污染内存中的字段,而这些内容不能被收集。”*因为何时变量_declared_在方法中是_field_? – Tom
一旦类加载器第一次加载类,一个类的静态成员将被初始化(因此也会分配内存)! – ParkerHalo
你是指静态方法的局部变量吗?没有这样的东西作为静态方法的实例变量。 –
*“在静态方法中创建实例变量是完全正确的”*是这样吗?你能向我们展示一个例子吗? – Tom