Static关键字和block块的经典小案例
public class StaticTest02 {
public static int id;
//类变量|静态变量--->类的静态变量在方法区的静态区中初始化id=0
public int age; //成员变量
public static void main(String[] args) {
StaticTest02 staticTest02 = new StaticTest02();
//实例化staticTest02在堆内存中开辟空间0X001-->成员变量跟随对象进入堆内存初始化 age=0
staticTest02.age=10;//对象引用为成员变量age赋值为10
System.out.println(StaticTest02.id);
// 输出类的静态变量值id=0
System.out.println(staticTest02.age);
//对象调用成员变量age输出为10
staticTest02.change();
//第一次调用成员方法,在堆内存中开辟空间0x002-->id=1 age=10 //id=1 staticTest02.age=1 方法使用完毕,栈帧释放
System.out.println(StaticTest02.id); //1
System.out.println(staticTest02.id);
//此处对象指的是0X001--->因此id是1
System.out.println(staticTest02.age);
//此处对象指的是0X001--> age=10
staticTest02.change();
//第二次调用change方法开辟堆空间-->0X003 第一句打印 :id=2 age=10(此处的age仍为0X001的age值)
// 第二句打印:id=2 staticTest02.age=1
System.out.println(id); //id=2
System.out.println(staticTest02.age);
//age=10
//当main方法执行完毕栈帧释放
}
public void change() {
StaticTest02 staticTest02 = new StaticTest02();
//实例化类对象staticTest02,成员变量跟随对象进入堆内存初始化 age=0
staticTest02.age++;//类对象的成员变量age:1
StaticTest02.id++;//类对象的类变量的id为1
System.out.println("In Change(): id = " + id + " age = " + age);
//第一次调用id=1 age=10
System.out.println("In Change(): id = " + id + " staticTest02.age = " + staticTest02.age);
//第一次调用 id=1 staticTest02.age=1
//id=2 staticTest02.age=10
}
}
1. block 块 {}->作用域
{} 局部代码块|普通语句块–>方法中或者语句块中 执行时机: 所在的方法调用
把相同逻辑的一段代码定义在块中,具有语义化,自成作用域
2. {} 构造块 -->类中方法外部 执行时机: new对象时候
对成员内容进行一些初始行为
3. static{} 静态块 —>类中方法外
对静态内容实现初始化
对一些配置…只需要执行一次,后续重复使用的代码可以定义在静态块中,做一些初始行为,不用封装方法调用
4. 同步块
注意:
static 成员修饰符 只能修饰成员变量不能修饰局部
局部变量不能被外部调用,因为存在于方法的栈帧中,跟随方法调用而存在,构造块代码先于构造器代码之前执行,如果出现多个构造块,从上到下依次执行
在类第一次加载完成之后就行初始化,并且只执行一次
如果存在多个静态块,丛上到下依次执行.
执行顺序:静态块 -> 主方法 -> 构造块 -> 构造器
/**
构造块的代码在编译期间会被编译到构造器代码中,在构造器代码之前
debug 调试工具
1.追踪程序的执行过程
2.定位,调试异常情况出现的位置
3.观察程序执行过程中变量的变化情况
4.学习源码了解执行过程
使用步骤:
1) 打断点
当程序执行到断点位置,停下来,之后的执行由程序猿自己控制
行号的后面单击打断点
2) debug环境运行
IDEA常用快捷键:
step over F8 继续执行下一步,如果下一步是方法的调用,不进入
step into F7 继续执行下一步,如果下一步是方法的调用,进入方法,如果是源码方法不进入
Force step into alt+shift+F7 继续执行下一步,如果下一步是方法的调用,强制进入方法,如果是源码方法强制进入
step out shift+f8 调出到方法调用的位置
**/
public class BlockTest02 {
public static int a = 0;
{
a = 10;
System.out.println("3 、非静态代码块执行a=" + a); //10
}
static {
a = 6;
System.out.println("1 、静态代码块执行a=" + a); //6
}
public BlockTest02() {
this(a); //6
System.out.println("6、"+a); //10
System.out.println("7、无参构造方法执行a=" + a); //10
}
public BlockTest02(int n) { //n=6
System.out.println("4 、"+n); //6
System.out.println("5、"+a);// 10
}
public static void main(String[] args) {
System.out.println("2 、main"); //main
BlockTest02 tsc = new BlockTest02();
System.out.println(tsc);
}
}