一 static关键字
特点:
1 static 修饰的成员可以被所有对象所共享。
2 static 优先于对象存在,随着类的加载而加载。
3 static 修饰的成员可以直接被类名所调用。
4 static 修饰的数据是共享数据,对象中存储的是特有数据
注意事项:
1 静态方法只能访问静态成员(非静态可以访问静态,又可以访问非静态)
2 静态方法中不可以使用this,super关键字(因为是共享的,没有具体的对象,所以不能使用)
1 static 方法(静态方法)
静态方法不依赖于任何对象就可以进行访问,对于静态方法,是不存在于this和super等关键字,因为不依附于任何对象。
所以的话,在静态方法中不能访问类的非静态变量和非静态成员方法,因为非静态成员方法/变量都是必须依附具体的对象才能够被调用。
注:
main方法中调用print2函数时,此时是不存在对象的,所以的话str2变量是不存在的,所有就会出现报错。
调用print1()方法也是如此,因为并不知道所调用的方法中是否有非静态变量/方法。
所以禁止静态方法中使用非静态变量和非静态方法。
2 static变量
static变量也称作静态变量,静态变量和非静态变量的区别是:
静态变量被所有的对象所共享,在内存中只有一个副本,它当且仅当在类初次加载时会被初始化。
而非静态变量是对象所拥有的,在创建对象的时候被初始化,存在多个副本,各个对象拥有的副本互不影响。
static成员变量的初始化顺序按照定义的顺序进行初始化。
3 static 代码块
static关键字还有一个比较关键的作用就是 用来形成静态代码块以优化程序性能。
static块可以置于类中的任何地方,类中可以有多个static块。
在类初次被加载的时候,会按照static块的顺序来执行每个static块,并且只会执行一次。
例:
class Person{
private Date birthDate;
public Person(Date birthDate) {
this.birthDate = birthDate;
}
boolean isBornBoomer() {
Date startDate = Date.valueOf("1998");
Date endDate = Date.valueOf("2000");
return birthDate.compareTo(startDate)>=0 && birthDate.compareTo(endDate) < 0;
}
}
此处每执行一次isBornBommer方法就会创建一次startDate和endDate对象,会造成空间浪费,效率就会减低。
使用静待代码块,在类初次被加载时,进行执行,且只会执行一次。
class Person{
private Date birthDate;
private static Date startDate,endDate;
static{
startDate = Date.valueOf("1946");
endDate = Date.valueOf("1964");
}
public Person(Date birthDate) {
this.birthDate = birthDate;
}
boolean isBornBoomer() {
return birthDate.compareTo(startDate)>=0 && birthDate.compareTo(endDate) < 0;
}
}
此时的话,对象只会在static代码块执行一次。
static关键字误区
1 static 关键字不会影响成员的访问权限
2 可以通过this访问静态成员变量吗
public class Main {
static int value = 33;
public static void main(String[] args) throws Exception{
new Main().printValue();
}
private void printValue(){
int value = 3;
System.out.println(this.value);
}
}
在main函数中使用new Main()中调用printValue的话,当前对象时new Main()之后生成的对象,又因为static是被对象所共享的所以输出的就是33
在printValue的value时局部变量,所以时与this是没有关系的,this表示也是当前的对象。
静态成员变量虽然独立于对象,但是不代表不可以通过对象去访问,所有的静态方法和静态变量都可以通过对象访问(只要访问权限足够)。
3 static不允许修饰局部变量(Java语法规定 )
4 static 和 final 一起使用
1 static 和 final 一起修饰 成员变量或者成员方法的话,就可以理解为"全局常量"!
2 对于变量,表示一旦给值,就通过类名可以访问。
3 对于方法,表示不可覆盖,并且可以直接通过类名进行访问。
二 final 关键字
在Java中,final关键字可以用来修饰类、方法和变量(包括成员变量和局部变量),表面就表示不可更改、恒定的意思。
1 final 变量
被final修饰的成员变量表示一个常量,只能被赋值一次,赋值之后不能被改变。
初始化方法:
1. 声明变量时被初始化
2. 在所在类的构造函数初始化
3. 在代码块中初始化
注意:
1. 修饰基本数据类型,基本数据类型的值初始化后就不能被改变。
修饰引用类型,引用的的地址的值是不能修改的,引用指向对象的内容是可以改变的。
2. 如果final修饰的是成员变量的话,则必须要进行初始化。
2 final 方法
被final修饰的方法不能被重写。
特别注意:
重写的前提需要是子类可以从父类中继承该方法,如果父类的final方法被private修饰的话,表示该类不能被子类继承,所以此时子类还是可以定义相同的方法名和参数。
例:
3 final 类
当final修饰类之后,表示这个类不能被继承。final类里的成员方法默认就是final类型的。