我们创建并初始化一个对象,往往有多种方法,多少人知道 {} 也是一种?这种方法独特,是不是一个良好的特性呢?
# 普通初始化
通常我们会这样创建对象并初始化,如下创建一个 List
List<Integer> list = new ArrayList<>(); | |
list.add(1); | |
list.add(2); | |
list.add(3); | |
System.out.println(list); |
主要分为两部分:1. 创建对象 2. 初始化数据
# 双大括号法
利用这种方法,我们可以把创建和初始化写在一起
List<Integer> list = new ArrayList<>()<!--swig0-->; | |
System.out.println(list); |
# 好处与坏处
好处
- 相对普通的看起来行数更少 (不考虑换行等)
- 可读性更高
- 创建和初始化在同一个表达式里完成了
坏处
- 并不是一个被广泛知道和使用的方法
- 每次使用它都会额外产生一个匿名类
第一层括号:实际是定义了一个匿名内部类 (Anonymous inner Class)
第二层括号:实际上是一个实例化初始化块 (Instance initializer block) 这个块在内部匿名类构造时被执行,这个块之所以被叫做 "实例化初始化块" 是因为它们被定义了一个类的实力范围内
解析原因
在 cmd 中,进行编译
javac TestHashMap.java
生成两个类
正如,双括号写法的原理一样,生成一个 Niubi666.class (外部实体类), 及 Niubi666$1.class (内部匿名类)
Niubi666.class (外部实体类)
public class Niubi666 { | |
static Map<Character,Integer> map = new HashMap<Character,Integer>()<!--swig1-->; | |
public static void main(String[]args){ | |
System.out.println(map); | |
System.out.println("Hello,java"); | |
} | |
} |
Niubi666$1.class (内部匿名类)
public class Niubi666 { | |
public static void main(String[]args){ | |
Map<Character,Integer> map = new HashMap<>(); | |
map.put('I',1); | |
System.out.println(map); | |
} | |
} |
- 不支持泛型推断 (List<String> list = new ArrayList<>())(也就是后面必须加泛型)
- 不支持 final 的类
- 会持有隐式的引用,这可能会导致内存泄露
其它更好的选择
使用 Stream 的工厂方法
list = Stream.of("Linux", "Windows", "Mac") | |
.collect(Collectors.toList()); | |
assertTrue(list.contains("Windows")); |
java9 可以使用 Collections 的工厂方法
List<String> list = List.of("Linux", "Wiondows", "Mac"); | |
Set<String> set = Set.of("Linux", "Wiondows", "Mac"); |