构造函数与初始化块

简介: 构造函数与初始化块

7-2 jmu-Java-03面向对象基础-02-构造函数与初始化块


1.定义一个Person类


属性:String name, boolean gender, int age, int id ,所有的变量必须为私有(private)。

无参构造函数:Person(), 功能:打印This is constructor 。

有参构造函数:Person(name, gender, age) ,功能:给属性赋值。

建议:使用Eclipse自动生成toString方法


2.定义类的初始化块


为Person类加入初始化块,在初始化块中对id属性赋值,并且要保证每次的值比上次创建的对象的值+1。然后在下一行打印This is initialization block, id is ... 其中...是id的值。

提示:可为Person类定义一个static属性来记录所创建的对象个数。


3.编写静态初始化块


打印This is static initialization block


4.编写main方法


  • 首先输入n,代表要创建的对象数量。
  • 然后从控制台分别读取n行的name, gender, age, 并调用有参构造函数Person(name, age, gender)新建对象 。
  • 将创建好的n个对象逆序输出(即输出toString()方法)。
  • 使用无参构造函数新建一个Person对象,然后直接打印该对象。


思考


初始化类与对象有几种方法,构造函数、初始化块、静态初始化块。这三种方法执行的先后顺序是什么?各执行几次。


输入样例:


3
a 11 false
b 12 true
c 10 false


输出样例:


This is static initialization block
This is initialization block, id is 0
This is initialization block, id is 1
This is initialization block, id is 2
Person [name=c, age=10, gender=false, id=2]
Person [name=b, age=12, gender=true, id=1]
Person [name=a, age=11, gender=false, id=0]
This is initialization block, id is 3
This is constructor
null,0,false,3
Person [name=null, age=0, gender=false, id=3]


代码:


package 测试;
import java.util.*;
public class Main {
  public static void main(String[] args) {
    // TODO Auto-generated method stub
    try (Scanner cin = new Scanner(System.in)) {
      int n = cin.nextInt();
      Person[] a = new Person[n];
      for (int i = 0; i < n; i++) {
        String name = cin.next();
        int age = cin.nextInt();
        boolean gender = cin.nextBoolean();
        a[i] = new Person(name, age, gender, i);
//        System.out.println(name + " " + age + " " + gender);
      }
      for (int i = n - 1; i >= 0; i--) {
        System.out.println(a[i].toString());
      }
      @SuppressWarnings("unused")
      Person b = new Person(n);
    }
  }
}
class Person {
  private String name;
  private boolean gender;
  private int age;
  private int id;
  static {
    System.out.println("This is static initialization block");
  }
  public Person(int id) {
    System.out.println("This is initialization block, id is " + id);
    System.out.println("This is constructor");
    System.out.println(name + "," + age + "," + gender + "," + id);
    System.out.println("Person " + "[name=" + name + ", age=" + age + ", gender=" + gender + ", id=" + id + "]");
  }
  public Person(String name, int age, boolean gender, int id) {
    super();
    System.out.println("This is initialization block, id is " + id);
    this.name = name;
    this.age = age;
    this.gender = gender;
    this.id = id;
  }
  @Override
  public String toString() {
    return "Person [name=" + name + ", age=" + age  + ", gender=" + gender+ ", id=" + id + "]";
  }
}


思考回答:


继承场景执行顺序:

父类静态初始化块->子类静态初始化块->父类非静态初始化块->父类构造函数->子类非静态初始化块->子类构造函数

非继承场景执行顺序:

静态初始化块->非静态初始化块->构造函数


静态初始化块:类加载时隐式调用

普通初始化块:创建对象时隐式调用


  •  静态初始化块的优先级最高,也就是最先执行,并且只在所有该类实例中的第一个实例初始化时执行;
  •    非静态初始化块和构造函数后执行,并且在每次生成类实例时执行一次;
  •   非静态初始化块的代码会在类构造函数之前执行。因此若要使用,应当养成把初始化块写在构造函数之前的习惯,便于调试;
  •    静态初始化块既可以用于初始化静态成员变量,也可以执行初始化代码;
  •    非静态初始化块可以针对多个重载构造函数进行代码复用。


目录
相关文章
|
4月前
|
编译器 C语言 C++
你想对构造函数说些什么?
你想对构造函数说些什么?
|
5月前
|
JavaScript 前端开发
构造函数。
构造函数。
18 1
|
8月前
|
编译器
匿名对象与构造器
匿名对象与构造器
48 0
|
9月前
|
安全 C#
C#视频之构造函数
C#视频之构造函数
44 0
|
9月前
|
Java 编译器
构造函数中为什么要用this关键字?
构造函数中为什么要用this关键字?
46 0
|
10月前
|
编译器 C语言 C++
C嘎嘎~~[构造函数提升篇]
C嘎嘎~~[构造函数提升篇]
|
10月前
|
Java 编译器
[构造函数]构造函数是如何产生的?
[构造函数]构造函数是如何产生的?
构造函数
构造函数
43 1