主要内容
包括静态代码块
、构造代码块
和局部代码块
的定义和特点还有具体的使用方法,最后补充了相关的变量的作用域与生命周期
、静态变量和静态方法
和this引用
的概念
1. 静态代码块
- 用
static
修饰的代码块,在类加载后就会被执行 - 静态代码块和静态方法相同,不能使用外部非静态成员
- 静态代码块执行和静态变量的初始化顺序一样,按代码从上到下
- 若某一段代码想在别人使用某个类的时候就运行, 而且只运行一次, 那么就可以写在静态代码块中
package inter;
public class StaticBlock {
public static StaticBlock block = null;
private String msg = "";
// 静态代码
static {
System.out.println("静态代码块开始执行");
// 创建一个对象
block = new StaticBlock("静态代码块信息");
}
// 调用外部静态方法
static {
printInfo();
}
public static void printInfo() {
System.out.println("静态代码块调用printInfo()");
}
public StaticBlock() {
System.out.println("无参构造");
// TODO Auto-generated constructor stub
}
public StaticBlock(String msg) {
System.out.println("有参构造:"+msg);
this.msg = msg;
}
public static void main(String[] args) {
System.out.println("main方法开始执行");
new StaticBlock();
}
}
运行结果
静态代码块开始执行
有参构造:静态代码块信息
静态代码块调用printInfo()
main方法开始执行
无参构造
2. 构造代码块
- 直接在类中定义且没有加
static
关键字的代码块,也称为实例代码块 - 构造代码块先于构造方法执行,每次创建对象前都会被调用
- 构造代码块可用于初始化实例成员的默认值
- 构造代码块中不能创建对象的实例
package inter;
/**
* @author wonzeng
* 2020年7月10日
*/
public class CodeBlock {
private CodeBlock block = null;
// 构造代码块
{
System.out.println("构造代码块开始执行");
// msg在后面定义,所以msg的并没有真正修改,因为被后面的定义的默认值覆盖了
msg = "构造代码块信息";
// 这样使用msg会报错没有定义,msg定义必须在当前代码块前面
// System.out.println("构造代码块执行完毕:"+msg);
// 不能在构造代码块中创建对象实例
// block = new CodeBlock();
}
private String msg = "初始信息";
private static CodeBlock imp = null;
public CodeBlock() {
System.out.println("创建实例对象");
}
public static void main(String[] args) {
System.out.println("main方法开始执行");
new CodeBlock();
}
}
运行结果
main方法开始执行
构造代码块开始执行
创建实例对象
3. 局部代码块
在局部位置用一对”{}
“包围的代码块,在里面定义的变量,其生命周期不能超出”{}
“之外
用于方法内部,其作用是限定当前变量的生命周期
综合前面,可以发现在以下执行顺序:静态代码块>
构造代码块,局部代码块的执行由出现的位置决定
package inter;
public class TempTest {
public TempTest() {
// TODO Auto-generated constructor stub
}
public static void main(String[] args) {
int N = 0;
// 局部代码块
{
// 修改外部变量
N = 10;
String msg = "局部代码块定义的字符串";
System.out.println(msg);
}
// 无法使用
// System.out.println(msg);
System.out.println(N);
String msg = "外部定义的字符串";
System.out.println(msg);
}
}
运行结果
局部代码块定义的字符串
10
外部定义的字符串
4. 相关概念
变量的作用域与生命周期
- 作用域:变量定义在哪一级大括号中,哪个大括号的范围就是这个变量的作用域,相同的作用域中不能定义两个同名变量
- 生命周期:变量的生命周期从定义时开始,超出作用域后结束,变量生命周期以外不能使用
静态变量和静态方法
- 使用
tatic
修饰,在类加载后可直接用类名访问,也可用对象名访问 - 通常是作为工具方法或者一个可以产生对象的方法被声明,是为了更方便使用,而不必创建对象
- 静态方法不能直接访问外部非静态成员,如需访问要在静态方法中创建该类的对象来访问
- 静态方法中不能使用
this
,super
关键字
this引用
- this通常用在构造方法、成员方法
- this表示对象自身的引用,每个类的实例都对应一个this引用
- 在类的static方法中不能使用this,因为static是不依赖于对象的,在对象还没有创建的时候自然地this也就不存在
package inter;
public class StaticImp {
private String msg = "";
public static int cnt = 0;
public static void printCnt() {
// 静态方法中,不能使用 this.cnt
System.out.println("输出静态常量:"+cnt);
}
public void display() {
System.out.println("msg的值:"+this.msg);
}
public StaticImp() {
// 构造方法中使用静态变量
StaticImp.cnt += 10;
msg += "修改值为"+StaticImp.cnt;
// TODO Auto-generated constructor stub
}
// static方法创建一个对象并返回
public static StaticImp getObject() {
StaticImp p = new StaticImp();
return p;
}
public static void main(String[] args) {
System.out.println("静态变量:"+StaticImp.cnt);
StaticImp.printCnt();
// 获得一个对象
StaticImp obj = getObject();
obj.display();
getObject().display();
}
}
运行结果
静态变量:0
输出静态常量:0
msg的值:修改值为10
msg的值:修改值为20