一、代码块
在Java语言中我们总是感受到当遇到一个难的东西,就用一个大括号把它括起来,这样被大括号括起来的代码块就叫代码块。代码块一共有四种:普通代码块、构造块、静态块、同步代码块。下面我们先介绍前三种代码块。
1.普通代码块
定义:普通代码块就是在定义在方法中的代码块,不管时什么方法都可以。普通代码块主要用于我们在一个类中,对于变量的命名重复了的解决方案。
举个栗子:
//1.普通代码块
public class Construction{
public static void main(String[] args){
int num=10;
System.out.println(num);
int num=100;
System.out.println(num);
}
}
对于以上这样的代码段编译时提示重复定义了,对于在同一个方法中的同一个变量我们只能定义一次,想要解决它就可以采用普通代码块,如下:
//1.普通代码块
public class Construction{
public static void main(String[] args){
{
int num=10;
System.out.println(num);
}
int num=100;
System.out.println(num);
}
}
通过一个大括号将有可能引起重复的代码段括起来,这样的话就可以在同一个方法中使用同一个变量了。
2.构造块
定义:定义在类中的方法块并且不要加修饰符
//2.构造块
class Person{
{
//定义在类中不加任何的修饰符
System.out.println("这是Person的构造块");
}
public Person(){//注意某个类的构造方法一定要在这个类里.
System.out.println("这是Person的构造方法");
}
}
public class Construction{
public static void main(String[] args){
new Person();//匿名对象:在创建某个类的一个对象的时候,就会调用它的构造方法,并且在调用构造方法之前要先执行构造块
new Person();//创建几次对象就执行几次构造块,构造块时和构造方法紧挨着的
}
}
从以上运行结果我们可以看出,构造块的执行在构造方法之前,并且每创建一个对象就会执行一次。
3.静态代码块(very 重要哦)
定义:故名思意,静态代码块就是一段代码被static修饰了。我们根据代码块的位置不同还对它进行了分类,分为在非主类中的静态代码块和在主类中的静态代码块。(非主类:一个类里面不含有mian方法;主类:含有main方法的这个类)下面我们通过代码来看这两种类型的代码块:
(1)在非主类中的代码块
//3.静态代码块
//(1)在主类中的静态代码块
class Person{
//以后在写代码的时候就按照执行的顺序来写,这样的话也有助于记住这个顺序
//静态块——》构造块——》构造方法
//静态块
static{
System.out.println("这是Person的静态块");
}
//构造块
//定义在类中不加任何的修饰符
{
System.out.println("这是Person的构造块");
}
//构造方法
public Person(){//注意某个类的构造方法一定要在这个类里.
System.out.println("这是Person的构造方法");
}
}
public class Construction{
public static void main(String[] args){
new Person();//匿名对象:在创建某个类的一个对象的时候,就会调用它的构造方法,并且在调用构造方法之前要先执行构造块
new Person();//创建几次对象就执行几次构造块,构造块时和构造方法紧挨着的
}
}
从上面的结果我们可以看出,静态块是最先执行的。并且静态块只执行一次,不管你实例化多少个对象它都只执行一次。
(2)在主类中的代码块
//3.静态代码块
//(1)在主类中的静态代码块
public class Construction{
//以后在写代码的时候就按照执行的顺序来写,这样的话也有助于记住这个顺序
//静态块——》构造块——》构造方法
//静态块
static{
System.out.println("这是Construction的静态块");
}
//构造块
//定义在类中不加任何的修饰符
{
System.out.println("这是Construction的构造块");
}
//构造方法
public Construction(){//注意某个类的构造方法一定要在这个类里.
System.out.println("这是Construction的构造方法");
}
public static void main(String[] args){
//new Construction();//匿名对象:在创建某个类的一个对象的时候,就会调用它的构造方法,并且在调用构造方法之前要先执行构造块
//new Construction();//创建几次对象就执行几次构造块,构造块时和构造方法紧挨着的
//System.out.println("main");
}
}
从主类中的代码块我们可以看出,静态块先于主方法执行。
需要注意的几点:
(1)对于非主类和主类中的静态块的main方法中为空静态块是否执行:
// //(1)在非主类的静态块
class Person{
// //以后在写代码的时候就按照执行的顺序来写,这样的话也有助于记住这个顺序
// //静态块——》构造块——》构造方法
// //静态块
static{
System.out.println("这是Person的静态块");
}
// //构造块
// //定义在类中不加任何的修饰符
{
System.out.println("这是Person的构造块");
}
// //构造方法
public Person(){//注意某个类的构造方法一定要在这个类里.
System.out.println("这是Person的构造方法");
}
}
public class Construction{
public static void main(String[] args){
//new Person();//匿名对象:在创建某个类的一个对象的时候,就会调用它的构造方法,并且在调用构造方法之前要先执行构造块
//new Person();//创建几次对象就执行几次构造块,构造块时和构造方法紧挨着的
}
}
从上面的运行代码我们可以看出在非主类的静态块中如果主方法什么都没写,它就不会执行静态块。
//(2)在主类中的静态代码块
public class Construction{
//以后在写代码的时候就按照执行的顺序来写,这样的话也有助于记住这个顺序
//静态块——》构造块——》构造方法
//静态块
static{
System.out.println("这是Construction的静态块");
}
//构造块
//定义在类中不加任何的修饰符
{
System.out.println("这是Construction的构造块");
}
//构造方法
public Construction(){//注意某个类的构造方法一定要在这个类里.
System.out.println("这是Construction的构造方法");
}
public static void main(String[] args){
//new Construction();//匿名对象:在创建某个类的一个对象的时候,就会调用它的构造方法,并且在调用构造方法之前要先执行构造块
//new Construction();//创建几次对象就执行几次构造块,构造块时和构造方法紧挨着的
//System.out.println("这是main方法");
}
}
就算main方法中没有任何执行语句,为空,静态块依然会执行。
(2)为什么静态块只执行一次并且为什么它比main方法还要先执行,以及为什么会出现上面的main为空在主类和非主类的静态代码块的执行结果不同
首先,静态块是在字节码加载JVM之前执行的,它是属于类的;JVM在找到类之前先找到它的.class文件,在找这个文件的过程中,只要看到了静态块中含有需要执行的语句就将它加载进去,这样的话内存中已经存放了一份了,后面将不再对它进行单独的执行,所以就只执行一次;对于静态块中没有执行语句的时候它不会将静态块加载进去。由于它在找到类之前就已经加载进去了,所以自然会比main方法先执行(简而言之,就是静态块对应的类中必须得有要执行的语句才会加载静态块)。对于上面出现的两种情况,是因为如果是非静态类的话,那个编译的类名就不是含有静态块的那个类,所以如果你的主类里面什么都不写那么就不会加载静态块,自然运行结果也没有。而主类中之所以可以加载静态块是因为拿的编译的文件名就是含有静态块的类名,所以当JVM寻找这个类名的时候自然就加载了在这个类中的静态块。
(3)静态块为空的时候
// //(2)在主类中的静态代码块
public class Construction{
// //以后在写代码的时候就按照执行的顺序来写,这样的话也有助于记住这个顺序
// //静态块——》构造块——》构造方法
// //静态块
static{
//System.out.println("这是Construction的静态块");
}
// //构造块
// //定义在类中不加任何的修饰符
{
System.out.println("这是Construction的构造块");
}
// //构造方法
public Construction(){//注意某个类的构造方法一定要在这个类里.
System.out.println("这是Construction的构造方法");
}
public static void main(String[] args){
// //new Construction();//匿名对象:在创建某个类的一个对象的时候,就会调用它的构造方法,并且在调用构造方法之前要先执行构造块
// //new Construction();//创建几次对象就执行几次构造块,构造块时和构造方法紧挨着的
System.out.println("这是main方法");
}
}
这个是当静态块为空的时候即是没有执行语句的时候JVM就不会加载静态块