Java花括号
1. 作用域
“作用域”很常用,所以不用再讲了。。。吗?1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29public class A extends B {
{ // 局部作用域
int a = 233;
}
private static int a;
static {
System.out.println("The initial value of a is " + a);
}
public static void fun(){
System.out.println("The is a function from A.");
}
public A() {
System.out.println("This is A, over.");
}
public static void main(String[] args) {
A a1 = new A();
B b1 = new A();
}
}
class B {
static {
System.out.println("Hello, I am B");
}
B() {
System.out.println("This is B, over.");
}
}
如果你能正确写出上述代码执行后的结果,那么确实不用看了。反之,你没有掌握。至于结果是什么,自己跑一跑便知。在这串代码中,在A类中有个局部作用域,在A,B中各自含有一个static
静态区域。
其中,局部作用域中的代码是不会影响局部作用域外的private static int a
的,而在类加载后,会将a
初始化成0。
static
静态区,类会在加载时编译,因此在实例化之前,就会输出。
2. 初始化数组
没什么的好讲的。
1 | String[] s = {"1","2","3"}; |
3. 匿名类
1 | new Thread(){ |
4. 双括号
通常情况下,初始化Java集合并向其中添加几个元素的步骤如下:1
2
3
4Set<Integer> set = new HashSet<>();
set.add(1);
set.add(2);
set.add(3);
我们也可以在静态区域中向作为静态变量的集合中添加元素:
1 | private static final Set<Integer> set = new HashSet<>(); |
此方法从语法上来看,这样的初始化方法虽然格式清晰明了,但语法上略显冗余。况且只能向“静态变量集合”中添加的约束,而“静态变量集合”只能作为一个类的内部私有属性,如果在”main”方法中便不能用了。
那么,双括号就出现了,也叫反模式
。你可以在”main”中使用:
1 | Set<Integer> set = new HashSet<Integer>() {{ |
也可以在类中,给类集合属性初始化:
1 | public class Main { |
这是比较特殊的用法。一般在做题的时候会遇到,考你的知识点,笔试时见到了不会自闭就够了。但是不建议使用,它可能会出现“内存溢出”的bug。
1 | Map source = new HashMap(){{ |
你可以试一试运行上述代码,表面上简洁的初始化代码,但是,编译器在为每个”双括号“实例化类型都创建了一个类,我们可以查看目录下的.class
文件:
其中带有$
符号的文件,如Main$2$1.class
是什么意思呢? 是Main
下有个匿名类,它管这个匿名类叫”2“,而”2“的下面还有一个匿名类,它管这个匿名类叫”1“。
如此的话,你运行一次没毛病,但是但是如果类似这样的代码存在于一个大型的应用中,这将增加 ClassLoader 一些不必要的负担。所以我们尽量不要为了省事儿,去写双括号的形式。