• Java技巧之双括弧初始化


    由于Java语言的集合框架中(collections, 如list, map, set等)没有提供任何简便的语法结构,这使得在建立常量集合时的工作非常繁索。每次建立时我们都要做:

    定义一个临时的集合类变量 建立一个空集合的实例,然后赋值给变量 将数据放入集合中 最后将集合做为参数传递给方法

    例如,要将一个Set变量传给一个方法:

    Set validCodes = new HashSet();
    validCodes.add("XZ13s");
    validCodes.add("AB21/X");
    validCodes.add("YYLEX");
    validCodes.add("AR2D");
    removeProductsWithCodeIn(validCodes);

    也可以用静态初始的方法

    private static final Set validCodes = new HashSet();
    static {
    validCodes.add("XZ13s");
    validCodes.add("AB21/X");
    validCodes.add("YYLEX");
    validCodes.add("AR2D");
    }
    private static final Set validCodes = new HashSet();
    static {
    validCodes.add("XZ13s");
    validCodes.add("AB21/X");
    validCodes.add("YYLEX");
    validCodes.add("AR2D");
    }

    其实,还有简结的方法,我们可以用双括弧语法(double-brace syntax)建立并初始化一个新的集合:

    private static final Set VALID_CODES = new HashSet() {{
    add("XZ13s");
    add("AB21/X");
    add("YYLEX");
    add("AR2D");
    }};
    private static final Set VALID_CODES = new HashSet() {{
    add("XZ13s");
    add("AB21/X");
    add("YYLEX");
    add("AR2D");
    }};

    或者

    removeProductsWithCodeIn(new HashSet() {{
    add("XZ13s");
    add("AB21/X");
    add("YYLEX");
    add("AR5E");
    }});
    removeProductsWithCodeIn(new HashSet() {{
    add("XZ13s");
    add("AB21/X");
    add("YYLEX");
    add("AR5E");
    }});

    第一层括弧 实际是定义了一个内部匿名类 (Anonymous Inner Class),第二层括弧 实际上是一个实例初始化块 (instance initializer block),这个块在内部匿名类构造时被执行。这个块之所以被叫做“实例初始化块”是因为它们被定义在了一个类的实例范围内。这和“静态初始化块 (static initialzer)”不同,因为这种块在定义时在括弧前使用了static关键字,因此它的和类在同一个范围内的,也就是说当类加载时就会被执行(更详情,可参考Java语言规范http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.6 )。实例初始化块中可以使用其容器范围内的所有方法及变量,但特别需要注意的是实例初始化块是在构造器之前运行的。

    这种方法只适用于不是final的类,因为final类是无法建立内部匿名子类,好在集合类都没有这个限制。因此,这种方法还可以被用来初始化其它任何对象,比如一个GUI对象:

    add(new JPanel() {{
    setLayout(...);
    setBorder(...);
    add(new JLabel(...));
    add(new JSpinner(...));
    }});
    add(new JPanel() {{
    setLayout(...);
    setBorder(...);
    add(new JLabel(...));
    add(new JSpinner(...));
    }});

    这样建立的内部匿名类的实例中包函它容器对像的引用。如果串行化(serialization)这个集合同时也会串行化它的内部类。

    另外,这种双括号初始化的方式针对map的初始化工作可以减少很多代码,请看:

                Map<String, Set<String>> baselineMap = new HashMap<>();
                final String schema = "schema";
                if (baselineMap.get(type) == null) {
                    baselineMap.put(type, new HashSet<String>() {{
                        add(schema);
                    }});
                } else {
                    baselineMap.put(type, new HashSet<String>(baselineMap.get(type)) {{
                        add(schema);
                    }});
                }

    这段代码我相信不用特别解释,基本都能看懂,想想如果不用双括号初始化的方式的话需要多写多少行代码!~

  • 相关阅读:
    mysql的基础增删改查(一)
    用sql的avg(score)求完平均值后,保存两位小数的方法(用于查询或视图)
    异常java.lang.IllegalArgumentException:attempt to create delete event with null entity
    jsp传到java的control层的方法
    Java基础知识整理(一)
    DataTables warning (table id = 'DataTables_Table_0');错误解决办法!
    关于HTML学习整理(一)
    jQuery EasyUI 数据网格
    EasyUI DataGrid分页数据绑定
    SQL输出矩阵
  • 原文地址:https://www.cnblogs.com/sidesky/p/9397998.html
Copyright © 2020-2023  润新知