类初始化
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;
}
}