java代码块
java代码块
基本介绍
代码化块又称为初始化块,属于类中的成员(即,是类的一部分),类似于方法,将逻辑语句封装在方法体中,通过{}包围起来。
没有方法名,没有返回值,没有参数,只有方法体,而且不用通过对象或类显式调用,而是加载类时,或创建对象时隐式调用
基本语法
[修饰符]{
代码}
注意:
- 修饰符可选,要写只能写static
- 代码块分为两类,使用static修饰的叫静态代码块,没有static修饰的叫普通代码块
- 逻辑语句可以写任意逻辑语句
代码块的好处和案例演示
-
相当于另一种形式的构造器(对构造器的补充机制),可以做初始化的操作
-
场景:如果多个构造器中都有重复的语句,可以抽取到初始化块中,提高代码的重用性
-
代码块的快速入门: CodeBlock01.java
class CodeBlock{ public static void main(String[] args) { move move = new move("y"); System.out.println("========="); move move1 = new move("x",100); System.out.println("========="); move move2=new move("z",100,"c"); } } class move{ private String name; private double price; private String director; /*public move(String name) { System.out.println("电影屏幕打开...."); System.out.println("电影广告..."); System.out.println("电影开始播放..."); System.out.println("调用move(String name)"); } public move(String name, double price) { System.out.println("电影屏幕打开...."); System.out.println("电影广告..."); System.out.println("电影开始播放..."); System.out.println("调用move(String name, double price)"); } public move(String name, double price, String director) { System.out.println("电影屏幕打开...."); System.out.println("电影广告..."); System.out.println("电影开始播放..."); System.out.println("调用move(String name, double price, String director)"); }*/ /** * 可以把相同的语句放到一个代码块中 * 这样当我们不管调用那个构造器,创建对象,都会先调用代码块的内容 * 代码块调用的顺序优先于构造器 */ { System.out.println("电影屏幕打开...."); System.out.println("电影广告..."); System.out.println("电影开始播放..."); } public move(String name) { System.out.println("调用move(String name)"); } public move(String name, double price) { System.out.println("调用move(String name, double price)"); } public move(String name, double price, String director) { System.out.println("调用move(String name, double price, String director)"); } }
输出:
电影屏幕打开.... 电影广告... 电影开始播放... 调用move(String name) ========= 电影屏幕打开.... 电影广告... 电影开始播放... 调用move(String name, double price) ========= 电影屏幕打开.... 电影广告... 电影开始播放... 调用move(String name, double price, String director) 进程已结束,退出代码为 0
代码块使用注意事项和细节讨论
一.static代码块
static代码块也叫做静态代码块,作用就是对类进行初始化,而且它随着类加载而加载,并且只执行一次,如果是普通代码块,每创建一个对象,就执行一次。
二.类什么时候被加载
-
创建对象实例时(new)
public class CodeBlockDetail01 { public static void main(String[] args) { //创建对象实例时(new) AA aa = new AA(); } } class AA{ //静态代码块 static{ System.out.println("AA的静态代码块"); } }
AA的静态代码块
-
创建子类对象实例,父类也会被加载
public class CodeBlockDetail01 { public static void main(String[] args) { //创建对象实例时(new) // AA aa = new AA(); //创建子类对象实例,父类也会被加载 AA aa1 = new AA(); } } class BB{ //静态代码块 static{ System.out.println("BB的静态代码块"); } } class AA extends BB{ //静态代码块 static{ System.out.println("AA的静态代码块"); } }
BB的静态代码块 AA的静态代码块
-
使用类的静态成员时
public class CodeBlockDetail01 { public static void main(String[] args) { //创建对象实例时(new) // AA aa = new AA(); //创建子类对象实例,父类也会被加载 // AA aa1 = new AA(); //使用类的静态成员时 System.out.println(Cat.n1); } } class Cat{ public static int n1=999;//静态属性 //静态代码块 static{ System.out.println("BB的静态代码块"); } }
Cat的静态代码块 999
public class CodeBlockDetail01 { public static void main(String[] args) { //创建对象实例时(new) // AA aa = new AA(); //创建子类对象实例,父类也会被加载 // AA aa1 = new AA(); //使用类的静态成员时 System.out.println(Cat.n1); } } class Animal{ //静态代码块 static{ System.out.println("Animal的静态代码块"); } } class Cat extends Animal{ public static int n1=999;//静态属性 //静态代码块 static{ System.out.println("Cat的静态代码块"); } }
Animal的静态代码块 Cat的静态代码块 999
三.普通代码块
普通代码块,在创建对象实例时,会内隐式的调用。
被创建一次,就会调用一次
如果只是使用类的静态成员时,普通代码块并不会被执行
public class CodeBlockDetail01 {
public static void main(String[] args) {
//创建对象实例时(new)
// AA aa = new AA();
//创建子类对象实例,父类也会被加载
// AA aa1 = new AA();
//使用类的静态成员时
// System.out.println(Cat.n1);
//static代码块也叫做静态代码块,作用就是对类进行初始化,而且它随着类加载而加载,并且只执行一次
//代码System.out.println("DD的静态代码块");会执行几次?
DD dd = new DD();
DD dd1 = new DD();
}
}
class DD{
//静态代码块
static{
System.out.println("DD的静态代码块");
}
}
DD的静态代码块
public class CodeBlockDetail01 {
public static void main(String[] args) {
//创建对象实例时(new)
// AA aa = new AA();
//创建子类对象实例,父类也会被加载
// AA aa1 = new AA();
//使用类的静态成员时
// System.out.println(Cat.n1);
//static代码块也叫做静态代码块,作用就是对类进行初始化,而且它随着类加载而加载,并且只执行一次
//代码System.out.println("DD的静态代码块");会执行几次?
// DD dd = new DD();
// DD dd1 = new DD();
//普通的代码块,在创建对象实例时,会被隐式的调用
//被创建一次,就会调用一次
//如果只是使用类的静态成员时,普通代码块并不会执行
System.out.println(DD.n);
}
}
class DD{
public static int n=999;
//静态代码块
static{
System.out.println("DD的静态代码块");
}
//普通代码块
{
System.out.println("DD的普通代码块");
}
}
DD的静态代码块
999
四.调用顺序
1.调用静态代码块和静态属性初始化(注意:静态代码块和静态属性初始化的优先级一样,如果有多个静态代码块和多个静态变量初始化,则按他们的顺序调用)
public class CodeBlockDetail02 {
public static void main(String[] args) {
A a = new A();
B b = new B();
}
}
class A{
//静态属性的初始化
private static int n1=getN1();
//静态代码块
static{
System.out.println("A 静态代码块");
}
public static int getN1(){
System.out.println("getN1被调用");
return 100;
}
}
class B{
//静态代码块
static{
System.out.println("B 静态代码块");
}
//静态属性的初始化
private static int n1=getN1();
public static int getN1(){
System.out.println("getN1被调用");
return 100;
}
}
getN1被调用
A 静态代码块
B 静态代码块
getN1被调用
2.调用普通代码块和普通属性的初始化(注意:普通代码块和普通属性初始化的优先级一样,如果有多个普通代码块和多个普通变量初始化,则按他们的顺序调用)
public class CodeBlockDetail02 {
public static void main(String[] args) {
A a = new A();
B b = new B();
}
}
class A{
//普通属性的初始化
private int n2=getN2();
//普通代码块
{
System.out.println("A 普通代码块");
}
//静态属性的初始化
private static int n1=getN1();
//静态代码块
static{
System.out.println("A 静态代码块");
}
public static int getN1(){
System.out.println("getN1被调用");
return 100;
}
public static int getN2(){
System.out.println("getN2被调用");
return 200;
}
}
class B{
//普通代码块
{
System.out.println("B 普通代码块");
}
//普通属性的初始化
private int n2=getN2();
//静态代码块
static{
System.out.println("B 静态代码块");
}
//静态属性的初始化
private static int n1=getN1();
public static int getN1(){
System.out.println("getN1被调用");
return 100;
}
public static int getN2(){
System.out.println("getN2被调用");
return 200;
}
}
getN1被调用
A 静态代码块
getN2被调用
A 普通代码块
B 静态代码块
getN1被调用
B 普通代码块
getN2被调用
3.调用构造方法
package CodeBlock.Block01;
public class CodeBlockDetail02 {
public static void main(String[] args) {
A a = new A();
B b = new B();
}
}
class A{
//普通属性的初始化
private int n2=getN2();
//普通代码块
{
System.out.println("A 普通代码块");
}
//静态属性的初始化
private static int n1=getN1();
//静态代码块
static{
System.out.println("A 静态代码块");
}
public static int getN1(){
System.out.println("getN1被调用");
return 100;
}
public static int getN2(){
System.out.println("getN2被调用");
return 200;
}
public A() {
System.out.println("A的构造器");
}
}
class B{
public B() {
System.out.println("B的构造器");
}
//普通代码块
{
System.out.println("B 普通代码块");
}
//普通属性的初始化
private int n2=getN2();
//静态代码块
static{
System.out.println("B 静态代码块");
}
//静态属性的初始化
private static int n1=getN1();
public static int getN1(){
System.out.println("getN1被调用");
return 100;
}
public static int getN2(){
System.out.println("getN2被调用");
return 200;
}
}
getN1被调用
A 静态代码块
getN2被调用
A 普通代码块
A的构造器
B 静态代码块
getN1被调用
B 普通代码块
getN2被调用
B的构造器
五.构造器
构造器的最前面其实隐含了 super()和 调用普通代码块,静态相关的代码块,属性初始化,在类加载时,就执行完毕,因此优先于构造器和普通代码块执行的
六.
我们看一下创建一个子类对象时(继承关系),他们的静态代码块,静态属性初始化,普通代码块,普通属性初始化,构造方法的调用顺序如下:
1.父类的静态代码块和静态属性(优先级一样,按定义顺序执行)
2.子类的静态代码块和静态属性(优先级一样,按定义顺序执行)
3.父类的普通代码块和普通属性初始化(优先级一样,按定义顺序执行)
4.父类的构造方法
5.子类的普通代码块和普通属性初始化(优先级一样,按定义顺序执行)
6.子类的构造方法/面试题
七.
7)静态代码块只能直接调用静态成员(静态属性和静态方法),普通代码块可以调用任意成员。
public class CodeBlockDetail04 {
public static void main(String[] args) {
//老师说明
//(1) 进行类的加载
//1.1 先加载 父类 A02 1.2 再加载 B02
//(2) 创建对象
//2.1 从子类的构造器开始
//new B02();//对象
new C02();
}
}
class A02 { //父类
private static int n1 = getVal01();
static {
System.out.println("A02 的一个静态代码块..");//(2)
}
{
System.out.println("A02 的第一个普通代码块..");//(5)
}
public int n3 = getVal02();//普通属性的初始化
public static int getVal01() {
System.out.println("getVal01");//(1)
return 10;
}
public int getVal02() {
System.out.println("getVal02");//(6)
return 10;
}
public A02() {//构造器
//隐藏
//super()
//普通代码和普通属性的初始化...... System.out.println("A02 的构造器");//(7)
}
}
class C02 {
private int n1 = 100;
private static int n2 = 200;
private void m1() {
}
private static void m2() {
}
static {
//静态代码块,只能调用静态成员
//System.out.println(n1);错误
System.out.println(n2);//ok
//m1();//错误
m2();
}
{
//普通代码块,可以使用任意成员
System.out.println(n1);
System.out.println(n2);//ok
m1();
m2();
}
}
class B02 extends A02 { //
private static int n3 = getVal03();
static {
System.out.println("B02 的一个静态代码块..");//(4)
}
public int n5 = getVal04();
{
System.out.println("B02 的第一个普通代码块..");//(9)
}
public static int getVal03() {
System.out.println("getVal03");//(3)
return 10;
}
public int getVal04() {
System.out.println("getVal04");//(8)
return 10;
}
//一定要慢慢的去品..
public B02() {//构造器
//隐藏了
//super()
//普通代码块和普通属性的初始化... System.out.println("B02 的构造器");//(10)
// TODO Auto-generated constructor stub
}
}