2015-11-12 196 views
0

什么时候静态方法的实例变量在java中获取内存? 在静态方法中创建实例变量(无论是在参数中还是在函数内声明)是完全正确的,但是我想知道什么时候静态方法的实例变量被分配了内存,如果没有创建类的对象?静态方法的Java实例变量

其实我的意思是说静态方法

+0

一旦类加载器第一次加载类,一个类的静态成员将被初始化(因此也会分配内存)! – ParkerHalo

+6

你是指静态方法的局部变量吗?没有这样的东西作为静态方法的实例变量。 –

+1

*“在静态方法中创建实例变量是完全正确的”*是这样吗?你能向我们展示一个例子吗? – Tom

回答

1

首先,术语instance variable是不准确的,我假设你是问关于local variableab在下面的例子如:

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

当方法存在时,2c被从堆栈中移除(实际上没有移除,但堆栈的顶部被改变为下面的两个位置,所以这些两个值将被覆盖,只要其他东西进入堆栈),而new C()将保留在堆中,直到垃圾收集器触发。由于GC可能会检测到没有更多此对象的引用,因此可能会立即收集垃圾。

+1

我认为从技术上讲,JLS从来没有将方法参数称为局部变量,但是在考虑这些参数时没有害处。 –

+1

以下是有关变量类型的JLS:https://docs.oracle.com/javase/specs/jls/se8/html/jls-4.html#jls-4.12.3 – Tom

+0

这很有趣,JLS与所有变种不同教程(包括Oracle教程)以及我们开发人员每天使用的术语。但好点,你们两个。 –

0

内的局部变量如果您声明一个变量或参数使用静态方法里面,它不是在所有的实例变量。一旦该方法被调用

static void methodTest(int i) { 

String s = "Hello"; 

} 

这里s是一个局部变量,以这种方法它是一个局部变量,它会被初始化。 和i是函数参数,它也是方法的局部变量

+6

本地变量's'将在调用方法时初始化,而不是在加载类时初始化。 –

0

在静态方法中没有这样的东西作为实例变量。

如果您指的是参数和局部变量,那么它们将在堆栈上分配(任何创建的对象都像往常一样分配在堆上)。

该类的静态字段将在加载类时初始化。

当构造实例时,类的实例变量将被分配(并可能被初始化)。

+0

你的意思是'stack'而不是'heap'(局部变量)?最后一句中可能是'instance fields',而不是'instance variables'。 –

+0

@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)。 –

-3

静态方法定义的变量仍然是方法范围内的局部变量,就好像非静态方法创建的局部变量一样。然而,问题是,只要类加载器(通常是主类,只在运行时终止时才“卸载”,就像用右手抓住左耳朵一样)没有被卸载并且垃圾集。只有当对象不再被引用时,对象才得到GC'd,并且在静态字段的情况下,由于我描述的行为,即使没有使用它们,它们也有被引用的倾向。因此,在大型应用程序中,内存和资源都是问题,在静态方法中声明任何内容是非常糟糕的想法,因为您很快会用无法收集的LOCAL VARIABLES污染内存。

+0

您不能在方法内声明静态字段。 –

+0

@PaulBoddington不,但保留局部变量的方法即使在执行后仍然被加载,因此其局部变量仍保留在堆栈中。上次我检查时,Java GC只收集卸载的类,而不是方法或字段。 –

+0

*“在静态方法中声明任何内容是非常糟糕的主意,因为你很快就会污染内存中的字段,而这些内容不能被收集。”*因为何时变量_declared_在方法中是_field_? – Tom