启动时静态引用变量和实例引用变量之间有什么区别?

时间:2016-08-05 09:17:52

标签: java

我对java中的一个基本内容感到困惑。

public class InitItself1 {

    public InitItself1(){}

    private InitItself1 me = new InitItself1();
}

当然我知道在创建上述类的实例时会发生StackOverFlowError。由于变量" me"

的启动,上述类将以递归方式启动。

但是,

public class InitItself2 {

    public InitItself2(){}

    private static InitItself2 me = new InitItself2();
}

当然是上述课程的结果," InitItself2"与先前的课程不同," InitItself1"。这很好用,没有发生错误。据我所知,在加载静态变量和块的类中执行启动静态变量和执行静态块。

让我感到困惑的是,我认为它与变量," me"相同。两个班级," InitItself1"和" InitItself2"已经启动了,并且它们也引用了它们所属的类,因此它看起来像是递归地启动了#34;会在启动这两个课程时发生。

我错过了什么意思? 请回答好。 谢谢:))

1 个答案:

答案 0 :(得分:2)

在第二种情况下,你不会得到StackOverFlowError。正如您自己所说,静态变量是在加载类时启动的,并且因为类只加载一次,所以静态class ImportExcel DEFAULT_MAPPING = { excel_col_name => db_colname }.freezy def initialize(mapping=nil, model_class=nil) @mapping = mapping || DEFAULT_MAPPING @model_class = model_class || DefaultModelClass end def import(excel_sheet) records = [] header = excel_sheet.first_row 2.upto(excel_sheet.last_row) do |line| record = @model_class.new records << record header.each_with_index do |name, col| record[@mapping[name]]= excel_sheet.row[line][col] end end records end end # Where ever importer = ImportExcel.new({ a: :b , c: :d}, MyModel) new_records = importer.import(sheet) new_records.map(&:save!) 只会被实例化一次。使用构造函数创建新对象不需要重新加载类。

InitItself2 me

提供以下输出

public final class InitItself {

    static {
        System.out.println("Class is loaded");
    }

    private static InitItself me = new InitItself();

    static {
        System.out.println("me is instantiated");
    }

    public InitItself() {
        System.out.println("Constructor called, me=" + me);
    }

    public static void main(String[] args) {
        System.out.println("START");
        InitItself i = new InitItself();
        System.out.println("FINISH");
    }
}
相关问题