本帖最后由 小石姐姐 于 2017-12-11 15:09 编辑
* 静态
* 关键字: static
* 作用: 修饰变量, 方法, 类, 该成员被所有对象共享
* 调用静态成员:
* 调用静态成员变量: 类名.静态成员变量
* 调用静态成员方法: 类名.静态成员方法
* 特点
* 被所有对象共享
* 直接使用类名调用
* 静态成员的加载优先于非静态的成员
* 静态成员的声明周期跟随类的加载加载
* 静态成员变量保存在内存中方法区中该类的字节码对象中的静态区域中
* 静态成员和非静态成员的区别
* 生命周期不同
* 静态成员: 跟随类的加载而创建, 随着程序的结束而销毁
* 非静态成员: 跟随对象的创建而创建, 跟随对象的销毁而销毁
* 内存中的位置不同
* 静态成员: 方法区中类的字节码对象中的静态区域中
* 非静态成员: 堆内存中对象区域中
* 初始化时机不同
* 静态成员: 类加载时初始化
* 非静态成员: 创建对象时初始化
* 静态方法的调用注意事项
* 非静态方法中, 可以调用静态和非静态的成员
* 静态方法中, 只能调用静态的成员
* 静态方法中能够使用this? 不能, 因为静态和非静态的生命周期不同
* 静态的优缺点:
* 优点:
* 共享数据保存在同一个存储空间中, 节省内存
* 可以直接类名调用, 简化代码编写
* 缺点:
* 访问有限制, 静态方法中只能访问静态成员
* 应用场景:
* 有需要共享的数据
* 工具类
* 把构造方法私有
* 所有方法用static修饰, 类名直接调用
* 代码块
* 概念: `{}`一对大括号引起来的就是代码块
* 分类:
* 局部代码块
* 定义位置: 方法中
* 执行时机: 调用方法时, 执行到局部代码块则执行
* 执行次数: 调用多少次方法能够执行到, 就执行多少次
* 作用: 限制局部变量的作用域
* 构造代码块
* 定义位置: 类中, 方法外
* 执行时机: 每次创建对象时执行, 优先于构造方法执行
* 执行次数: 创建多少次对象, 就执行多少次
* 作用: 抽取构造方法共同执行的代码, 简化书写
* 静态代码块
* 定义位置: 类中, 方法外, 前面要加static
* 执行时机: 类加载时执行
* 执行次数: 只有一次
* 作用: 在类加载时进行一些初始化操作
* 同步代码块(多线程讲)
## 代码块面试题
* 5分钟练习: 代码块练习
* 继续使用项目s2-day01, 建包com.itheima.practice_06
* 定义BlockTest类
* 定义静态代码块: 输出"BlockTest静态代码块被执行"
* 定义构造代码块: 输出"BlockTest构造代码块被执行"
* 定义无参构造方法: 输出"BlockTest无参构造执行"
* 定义main方法: 创建Coder对象
* 在BlockTest类中定义Coder类, 去掉public修饰
* 定义静态代码块: 输出"Coder静态代码块被执行"
* 定义构造代码块: 输出"Coder构造代码块被执行"
* 定义无参构造方法: 输出"Coder无参构造执行"
* 注意定义类时的问题:
* 一个文件中只能有一个public修饰的class, 其他可以不写public
```java
/*
定义一个BlockTest类:
在该类中定义静态代码块,在静态代码块中输出”BlockTest静态代码块被执行”
在该类中定义构造代码块,在构造代码块中输出”BlockTest构造代码块被执行”
在该类中定义无参构造,在无参构造中
输出”BlockTest无参构造执行”
定义一个Coder类
该类中定义的内容与BlockTest完全相同
在BlockTest中定义main方法,创建Coder()对象,测试程序执行结果
执行顺序
BlockTest静态代码块被执行
Coder静态代码块被执行
Coder构造代码块被执行
Coder无参构造执行
*/
public class BlockTest {
// 静态代码块
static {
System.out.println("BlockTest静态代码块被执行");
}
// 构造代码块
{
System.out.println("BlockTest构造代码块被执行");
}
// 构造方法
public BlockTest() {
System.out.println("BlockTest无参构造执行");
}
public static void main(String[] args) {
// 创建对象
Coder coder = new Coder();
}
}
class Coder {
// 静态代码块
static {
System.out.println("Coder静态代码块被执行");
}
// 构造代码块
{
System.out.println("Coder构造代码块被执行");
}
// 构造方法
public Coder() {
System.out.println("Coder无参构造执行");
}
}
```
* 执行流程
```
1. BlockTest静态代码块执行
程序主入口是main()方法, 要调用main()方法需要先加载main()方法所在的类, 即BlockTest类, 加载类时, 静态代码块执行
2. BlockTest的main()方法执行
程序先从main()方法执行
3. Coder静态代码块执行
创建c1对象的前提是加载Coder类, 所以加载Coder类后静态代码块执行
4. Coder构造代码块执行
创建对象时, 构造代码块优先于构造方法执行
5. Coder无参构造方法执行
创建对象时执行 |
|