类的成员之四:代码块(或者初始化快)
-
1.代码块的作用:用来初始化类或者是对象
-
2.代码块如果有修饰的话,只能有static
-
3.分类:静态代码块、非静态代码块
-
4.静态代码块:
>内部可以有输出语句
>随着类的加载而执行,而且只执行一次
>作用:初始化类的信息
>如果一个类中定义了多个静态代码块,则按照声明的先后顺序执行
>静态代码块的执行优先于非静态代码块的执行。
>静态代码块内只能调用静态属性或者方法,不能调用非静态结构 -
5.非静态代码块:
>内部可以有输出语句
>随着对象的创建而执行
>每创建一个对象,执行一次非静态代码块
>作用:可以在创建对象时,对对象的属性进行初始化
>非静态代码块可以调用静态属性、方法、非静态属性、方法 -
对属性可以赋值的位置:
①默认初始化
②显示初始化
③构造器中初始化
④有了对象以后,可以通过“对象.属性”的的方式,进行赋值
⑤在代码块中赋值
public class BlockTest {
public static void main(String[] args) {
String desc = Person.desc;
System.out.println(desc);
Person p1 = new Person();
Person p2 = new Person();
System.out.println(p1.age);
Person.info();
}
}
class Person{
//属性
String name;
int age;
static String desc = "我是一个人";
//构造器
public Person(){
}
public Person(String name, int age){
this.name = name;
this.age = age;
}
//static代码块
static{
System.out.println("hello, static block-1");
desc = "我是一个爱学习的人";//对类中静态属性进行赋值
}
static{
System.out.println("hello, static block-2");
info();
// eat();//不能调用非静态
}
//非静态代码块
{
System.out.println("this is non static block");
//调用非静态结构
age = 1;
eat();
//调用静态结构
desc = "我是一个爱学习的人";
info();
}
//方法
public void eat(){
System.out.println("吃饭");
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public static void info(){
System.out.println("I am a happiness boy");
}
}
练习
/*
* 总结:由父及子,静态先行
* */
public class LeafTest {
public static void main(String[] args) {
new Leaf();
System.out.println();
new Leaf();
}
}
//先加载1(显示static代码块)
class Root{
static {
System.out.println("Root的静态初始化块");
}
{
System.out.println("Root的普通初始化块");
}
public Root(){
//super();//->object
System.out.println("Root的无参数的构造器");
}
}
//2
class Mid extends Root {
static {
System.out.println("Mid的静态初始化块");
}
{
System.out.println("Mid的普通初始化块");
}
public Mid() {
//super();//默认省略
System.out.println("Mid的无参数的构造器");
}
public Mid(String msg){
//通过this调用同一类中重载的构造器
this();
System.out.println("Mid的带参数的构造器" + msg);
}
}
//3
class Leaf extends Mid{
static {
System.out.println("Leaf的静态初始化块");
}
{
System.out.println("Leaf的普通初始化块");
}
public Leaf() {
//通过super调用父类中有一个字符串参数的构造器
super("123");
System.out.println("Leaf的无参数的构造器");
}
}
练习二
public class Son extends Father{
static {
System.out.println("44444444");
}
{
System.out.println("55555555");
}
public Son(){
System.out.println("66666666");
}
public static void main(String[] args) {
System.out.println("77777777");
System.out.println("****************************");
new Son();
System.out.println("****************************");
new Son();
System.out.println("****************************");
new Father();
}
}
class Father{
static {
System.out.println("11111111");
}
{
System.out.println("22222222");
}
public Father(){
System.out.println("33333333");
}
}
对属性可以赋值的位置:
- ①默认初始化
- ②显示初始化
- ③构造器中初始化
- ④有了对象以后,可以通过“对象.属性”的的方式,进行赋值
- ⑤在代码块中赋值
- 执行先后顺序①-②/⑤-③-④
- ②/⑤根据代码编写先后顺序看
public class OrderTest {
public static void main(String[] args) {
Order order = new Order();
System.out.println(order.orderId);
}
}
class Order{
//先后顺序不同,数值不一样
// {
// orderId = 4;
// }
int orderId = 3;
{
orderId = 4;
}
}