今天学习的内容是静态
通过之前的学习,我们基本了解了静态变量和静态方法的知识,下面做一些总结和补充:
- 由static关键字修饰的成员变量和成员方法称作静态变量和静态方法
- static关键字不能修饰局部变量
- 调用静态变量和静态方法的格式:类.变量和类.方法(也可以使用对象调用,不过不推荐)
- 静态变量和静态方法同样遵循权限修饰符的约束
- 当实例变量不会影响某个方法的行为,那么最好将这个方法设置为静态的
- 静态方法中不能使用this和super关键字
- 静态方法中不能直接调用非静态变量和非静态方法
- 在静态方法内部调用本类的静态变量或静态方法,直接调用即可,实际上这是由于编译器帮着自动添加了类名
- 静态变量于类第一次加载时存储在方法区,无论如何都会先被默认初始化(实例变量也一样)
- 静态变量是被所有对象共享的数据,非静态变量就是对象特有的数据(共享区域要看权限修饰符)
- 静态变量直到应用程序结束才会被销毁(所以最好不要随意定义静态变量)
- 在类中定义的static{}称为静态代码块,与静态方法的规则相同,它会在类首次加载时执行,用于初始化类。有的类无法创建对象(抽象类或者构造函数为private的类),所以只能使用静态代码块初始化(比如JDBC类)
- 在类中定义的{}称为构造代码块,它会在构造函数之前执行,创建几个对象就执行几次,用于初始化所有对象。注意在方法中定义的{}是局部代码块,用来控制某些变量的生命周期。
- 实例变量和静态变量的初始化顺序:默认初始化-->指定初始化-->静态代码块初始化(只能初始化静态变量)-->构造代码块初始化-->构造函数初始化
- 静态变量是在类首次加载时进行默认初始化和指定初始化的,而实例变量是在要创建对象时才会默认初始化和指定初始化的
- 使用代码块初始化的某种可能是:初始化程序有多行
- 如果某类之前没有被加载过,那么调用构造函数、静态变量和静态方法均会引起该类的加载
示例程序:
public class Test27 {
private int a;//默认初始化
private static int count;//默认初始化
static int num=1;//指定初始化
static String name;//默认初始化
//静态代码块,会在类加载时执行,而且只执行一次,用于给类进行初始化
//因为有些类不需要创建对象,不能通过构造函数初始化,所以只能通过静态代码块初始化类
static{
//!a=1; 静态代码块与静态方法的规则相同
System.out.println("默认初始化的name:"+name);//null
System.out.println("指定初始化的num:"+num);//1
name="haha";//静态代码块初始化
for(int i=0;i<10;i++){
num+=i; //静态代码块初始化
}
System.out.println("静态代码块初始化的name:"+name);//haha
System.out.println("静态代码块初始化的num:"+num);//46
}
//构造代码块,在调用构造函数之前执行,创建几个对象调用几次,给所有对象初始化
{
name="hehe";
num=num+1;
System.out.println("构造代码块初始化的name:"+name);
System.out.println("构造代码块初始化的num:"+num);
}
public Test27(){
name="heihei";
num=num+1;
System.out.println("构造函数初始化的name:"+name);
System.out.println("构造函数初始化的num:"+num);
count++;
System.out.println("第"+count+"次创建对象");
}
public static void main(String[] args){//new String[0]
System.out.println(args);//[Ljava.lang.String;@6a2437ef
System.out.println(Arrays.toString(args));//[]
System.out.println(args.length);//0
System.out.println("-------------In main--------------");
for(int i=0;i<3;i++){
new Test27();
}
System.out.println("一共创建了"+count+"个对象");//与this同理,编译器帮着自动添加了类名,Test27.count
print();//与this同理,编译器帮着自动添加了类名,Test27.print();
}
//实例变量不会影响这个方法的行为,最好将它设置为静态的
public static void print(){
//!static int i; 局部变量不能被static关键字修饰
//!System.out.println(a); 静态方法不能直接调用费静态成员
//!System.out.println(this); 静态方法不能使用this
//!System.out.println(super.toString()); 静态方法不能使用super
System.out.println("一共创建了"+count+"个对象");//与this同理,编译器帮着自动添加了类名,Test27.count
}
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
}