类初始化的基本知识

类初始化

static:也是一种修饰符

  • 1、意思:静态的

  • 2、可以修饰什么?

     	(1)方法   //静态方法在编译期间就确定了,不需要在运行时动态绑定(不能被重写)
     	(2)成员变量
     	(3)内部类:后面讲
     	(4)代码块
    
  • 3、修饰后有什么不同?

     (1)方法:我们称为“静态方法”或“类方法”
     (2)成员变量:称为“类变量、静态变量”
     (3)内部类:后面讲
     (4)代码块
    
  • (1)方法:我们称为“静态方法”或“类方法”

     ①这个方法,对于其他类来说可以用"类名.方法"进行调用,当然也可以使用
     "对象名.方法"进行调用,我们推荐用"类名.方法"
     ②静态方法中,是不允许出现:this,super,对本类的非静态属性、非静态的方法的直接使用代码的
    
  • (2)成员变量:称为“类变量、静态变量”

      ①用static修饰的成员变量的值,表示是这个类型的所有对象“共享的”
      ②static修饰的成员变量的值,存储在方法区
      ③static修饰的成员变量的get/set也是静态的,
      ④如果在方法中有局部变量与static修饰的成员变量同名时,在静态变量前面加"类名."进行区别
    
  • 结论:非静态的"对象名.",静态的用"类名."

(4)代码块
非静态代码块:

【修饰符】 class 类{ 
		{
  			非静态代码块
  		}
  }

静态代码块:

  【修饰符】 class 类{
 		static{
 			静态代码块
 		}
  }
  • 特点:
  • (1)每一个类的静态代码块只会执行一次
  • (2)静态代码块在第一次使用这个类之前执行,即在类初始化时执行。

4、类初始化即执行类初始化方法:()

  • 类初始化方法,一个类只有一个。它也是有编译器编译生成的,由两部分代码组成:

     (1)静态变量的显式赋值代码
     (2)静态代码块的代码
    
  • 其中(1)和(2)是按照顺序执行

  • 回忆:实例初始化方法()或(形参列表)

  • 一个类可能有好几个实例初始化方法,有几个构造器就有几个实例初始化方法,它们由编译器根据:

      ①成员变量的显式赋值代码
     ②非静态代码块代码
     ③构造器的代码
    
  • initialize:初始化

  • class initialize:类初始化

public class TestStatic2 {
    
    
	static{
    
    
		System.out.println("TestStatic2静态代码块");
	}
	public static void main(String[] args) {
    
    
		/*MyClass.test();
		MyClass.test();
		MyClass.test();
		MyClass.test();*/
		
/*		MyClass my1 = new MyClass();
		MyClass my2 = new MyClass();
		MyClass my3 = new MyClass();*/
		
		Demo d = new Demo();//现在第一次使用Demo类,用它创建一个对象时,会导致Demo类的初始化
	}
}

class MyClass{
    
    
	static{
    
    
		System.out.println("MyClass静态代码块");
	}
	
	public static void test(){
    
    
		System.out.println("静态方法");
	}
	
}

class Demo{
    
    
	static{
    
    
		System.out.println("(1)Demo的静态代码块1");
	}
	private static String info = assign();
	static{
    
    
		System.out.println(info);
		System.out.println("(2)Demo的静态代码块2");
	}
	public static String assign(){
    
    
		System.out.println(info);
		System.out.println("(3)assign()方法");
		return "hello";
	}
}

在这里插入图片描述
在这里插入图片描述

  • 一个类初始化时会先检查它的父类是否初始化,如果父类没有初始化,那么会先初始化父类。因为一个类只要初始化一次。

  • (1)父类的初始化()

     ①父类的静态变量的显式赋值
     ②父类的静态代码块
    
  • (2)子类的初始化()

     ①父类的静态变量的显式赋值
     ②父类的静态代码块
    
  • 特殊:

  • 静态方法是不能被重写的

public class TestClassInit {
    
    
	public static void main(String[] args) {
    
    
		/*Father f = new Father();
		System.out.println("-------------------");
		Son s = new Son();*/
		
		Son s = new Son();
		
		/*Father f = new Son();//多态引用
		System.out.println("----------------");
		f.assign();//静态方法在编译期间就确定了,不需要在运行时动态绑定
*/	}
}
class Father{
    
    
	private static String info = assign();
	static{
    
    
		System.out.println("(1)父类的静态代码块");
	}
	public static String assign(){
    
    
		System.out.println("(3)assign()方法");
		return "Father";
	}
}
class Son extends Father{
    
    
	private static String info = assign();
	static{
    
    
		System.out.println("(2)子类的静态代码块");
	}
	public static String assign(){
    
    
		System.out.println("(4)assign()方法");
		return "Son";
	}
}

在这里插入图片描述

  • 1、类的初始化
  • 2、实例初始化
    (代码先完成类初始化后完成实例初始化)
public class TestInit {
    
    
	public static void main(String[] args) {
    
    
		Demo d = new Demo();//2631745
	}
}
class Demo{
    
    
	{
    
    
		System.out.println("(1)Demo的非静态代码块1");
	}
	static{
    
    
		System.out.println("(2)Demo的静态代码块1");
	}
	private static String info = assign();
	private String message = getMessage();
	static{
    
    
		System.out.println("(3)Demo的静态代码块2");
	}
	{
    
    
		System.out.println("(4)Demo的非静态代码块2");
	}
	public Demo(){
    
    
		System.out.println("(5)无参构造");
	}
	public static String assign(){
    
    
		System.out.println("(6)assign()方法");
		return "hello";
	}
	public String getMessage(){
    
    
		System.out.println("(7)getMessage()方法");
		return "msg";
	}
}

在这里插入图片描述

执行步骤

  • (1)先完成父类的类初始化
  • (2)再完成子类的类初始化
  • (3)父类的实例初始化方法
  • (4)子类的实例初始化方法

public class TestInit2 {
    
    
	public static void main(String[] args) {
    
    
		DemoZi zi1 = new DemoZi();
		//System.out.println("-------------------");
		//DemoZi zi2 = new DemoZi();
	}
}
class DemoFu{
    
    
	{
    
    
		System.out.println("(1)Demo的非静态代码块1");
	}
	static{
    
    
		System.out.println("(2)Demo的静态代码块1");
	}
	private static String info = assign();
	private String message = getMessage();
	static{
    
    
		System.out.println("(3)Demo的静态代码块2");
	}
	{
    
    
		System.out.println("(4)Demo的非静态代码块2");
	}
	public DemoFu(){
    
    
		System.out.println("(5)无参构造");
	}
	public static String assign(){
    
    
		System.out.println("(6)assign()方法");
		return "hello";
	}
	public String getMessage(){
    
    
		System.out.println("(7)getMessage()方法");
		return "msg";
	}
}
class DemoZi extends DemoFu{
    
    
	{
    
    
		System.out.println("(8)");
	}
	static{
    
    
		System.out.println("(9)");
	}
	private static String info = assign();
	private String message = getMessage();
	static{
    
    
		System.out.println("(10)");
	}
	{
    
    
		System.out.println("(11)");
	}
	public DemoZi(){
    
    
		System.out.println("(12)");
	}
	public static String assign(){
    
    
		System.out.println("(13)");
		return "hello";
	}
	public String getMessage(){
    
    
		System.out.println("(14)getMessage()方法");
		return "msg";
	}
}

在这里插入图片描述

  • (1)Father类的类初始化

     	①类变量显式赋值:这里没有
     	②静态代码块
    

    System.out.println("(1)父类的静态代码块");

  • (2)Son类的类初始化

     ①类变量显式赋值:这里没有
     ②静态代码块
    

    System.out.println("(4)子类的静态代码块");

  • (3)执行Father类的是实参初始化方法()

     ①非静态成员变量的显式赋值:这里没有
     ②非静态代码块:
    

    System.out.println("(2)父类的非静态代码块");

     ③父类的无参构造
    

    System.out.println("(3)父类的无参构造");

  • (4)执行Son类的实例初始化方法()

     ①非静态成员变量的显式赋值:这里没有
     ②非静态代码块:
    

System.out.println("(5)子类的非静态代码块");

	 ③子类的无参构造

System.out.println("(6)子类的无参构造");

public class TestExer1 {
    
    
	public static void main(String[] args) {
    
    
		Son son = new Son();
	}
}
class Father{
    
    
	static{
    
    
		System.out.println("(1)父类的静态代码块");
	}
	{
    
    
		System.out.println("(2)父类的非静态代码块");
	}
	Father(){
    
    
		System.out.println("(3)父类的无参构造");
	}
}
class Son extends Father{
    
    
	static{
    
    
		System.out.println("(4)子类的静态代码块");
	}
	{
    
    
		System.out.println("(5)子类的非静态代码块");
	}
	Son(){
    
    
		System.out.println("(6)子类的无参构造");
	}
}
/*
 * (1)Fu类的类初始化
 * ①类变量显式赋值:
 * 		i = getNum("(1)i");
 * 		public static int getNum(String str){
			print(str);
				public static void print(String str){
					System.out.println(str + "->" + i);			(1)i -> 0(默认值)
				}
			return ++i;										i=1
		}
 * ②静态代码块
 * 	static{
		print("(3)父类静态代码块");
			public static void print(String str){
				System.out.println(str + "->" + i);			  (3)父类静态代码块 -> 1
			}
	}
 * (2)Zi类的类初始化
 * ①类变量显式赋值:
 * 	  k = getNum("(6)k");
	 * 	
		public static int getNum(String str){
			print(str);
				public static void print(String str){
					System.out.println(str + "->" + k);		(6)k -> 0(默认值)
				}
			return ++k;									k=1
		}
 * ②静态代码块
 * 	static{
		print("(8)子类静态代码块");
			public static void print(String str){
				System.out.println(str + "->" + k);		(8)子类静态代码块 -> 1
			}
	}	
 * 
 * (3)执行Fu类的是实参初始化方法<init>()
 * ①非静态成员变量的显式赋值:
 * 		j = getNum("(2)j");
	 * 	
		public static int getNum(String str){
			print(str);
					public static void print(String str){
						System.out.println(str + "->" + i);  (2)j -> 1
					}
			return ++i;								i=2
		}
 * ②非静态代码块:
 * 	{
		print("(4)父类非静态代码块,又称为构造代码块");
				public static void print(String str){
					System.out.println(str + "->" + i);  (4)父类非静态代码块,又称为构造代码块 -> 2
				}
	}	
 * ③父类的无参构造
 *	Fu(){
		print("(5)父类构造器");
				public static void print(String str){
					System.out.println(str + "->" + i);  (5)父类构造器 -> 2
				}
	} 		
 * 
 * (4)执行Zi类的实例初始化方法<init>()
 * ①非静态成员变量的显式赋值:
 * 	 h = getNum("(7)h");

	public static int getNum(String str){
		print(str);
			 * 	public static void print(String str){
					System.out.println(str + "->" + k);   (7)h ->1
				}
		return ++k;									k=2
	}
 * 
 * ②非静态代码块:
 * 	{
		print("(9)子类非静态代码块,又称为构造代码块");
			public static void print(String str){
					System.out.println(str + "->" + k);   (9)子类非静态代码块,又称为构造代码块 ->2
			}
	}	
 * ③子类的无参构造
 * 	Zi(){
		print("(10)子类构造器");
			public static void print(String str){
					System.out.println(str + "->" + k);   (10)子类构造器 ->2
			}
	}	
 */
public class TestExer2 {
    
    
	public static void main(String[] args) {
    
    
		Zi zi = new Zi();
	}
}
class Fu{
    
    
	private static int i = getNum("(1)i");
	private int j = getNum("(2)j");
	static{
    
    
		print("(3)父类静态代码块");
	}
	{
    
    
		print("(4)父类非静态代码块,又称为构造代码块");
	}
	Fu(){
    
    
		print("(5)父类构造器");
	}
	public static void print(String str){
    
    
		System.out.println(str + "->" + i);
	}
	public static int getNum(String str){
    
    
		print(str);
		return ++i;
	}
}
class Zi extends Fu{
    
    
	private static int k = getNum("(6)k");
	private int h = getNum("(7)h");
	static{
    
    
		print("(8)子类静态代码块");
	}
	{
    
    
		print("(9)子类非静态代码块,又称为构造代码块");
	}
	Zi(){
    
    
		print("(10)子类构造器");
	}
	public static void print(String str){
    
    
		System.out.println(str + "->" + k);
	}
	public static int getNum(String str){
    
    
		print(str);
		return ++k;
	}
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_42481940/article/details/106979591