Java基础——final和static关键字
1.final关键字
final关键字代表“最终的”,“不可变的”
1.1 修饰变量
- 成员变量—代表当前变量是一个常量,存于方法区中。必须被显式的初始化,即可以在定义时进行初始化,也可以在构造函数中进行初始化!
- 局部变量-变量在整个作用域中不可变!
public void function(){ final int age = 0; //这个被final修饰的局部变量只要在用之前进行初始化就好了,不用像成员变量一样显式的初始化 age ++; //报错!!!final类型不可变! }
1.2 修饰方法
final修饰方法代表方法不可被子类重写!!!private方法被隐式的指定为final!!!
1.3 修饰类
final修饰类代表类不能被继承!!!
final的优点
- final关键字提高了性能。JVM和Java应用都会缓存final变量。
- final变量可以安全的在多线程环境下进行共享,而不需要额外的同步开销。比如String底层就是一个final类型的数组,所以String类型是线程安全的!
- 使用final关键字,JVM会对方法、变量及类进行优化。
2.static关键字
2.1 静态导包
import static java.lang.Math.*
public class Test{
public static void main(String[] args){
int a = abs(-1); //可以直接省略[Math.]
}
}
2.2 修饰变量
与实例变量最大的区别在于static修饰的变量属于类的,是类变量,而普通的成员变量则属于实例的,与实例同生共死。毕竟类变量放在方法区中,实例变量与对象一起放在堆中!
2.3 修饰方法
与变量一样,static修饰的方法属于类的!
- 类方法随着类的加载而加载,各个对象共享一份!而普通方法则随着对象的创建加载
- 类方法只能调用外部类变量,而普通方法随便都可以调用
- 类方法内部可使用的关键字有限,比如不能使用super和this!!而普通方法无所谓
2.4 修饰代码块
修饰代码块的时候,规则与修饰方法类似:在类的加载的时候加载一次,只能调用静态变量,受限关键字
重点:当一段代码的执行涉及到父子类的静态变量,静态代码块以及成员变量和普通代码块的时候,他们的执行先后顺序是怎样的?
父类的静态变量和静态代码块
子类的静态变量和静态代码块
父类的实例变量和普通代码块
父类的构造函数
子类的实例变量和普通代码块
子类的构造函数
2.5 修饰内部类
内部类的一种,静态内部类不依赖于外部类,而普通内部类其实例化必须依赖于外部类的实例化!!!
延申: 谈谈Java内部类
在 Java 中,可以将一个类定义在另一个类中或者一个方法中,这样的类称为内部类。广泛意义上的内部类一般来说包括这四种:成员内部类、局部内部类、匿名内部类和静态内部类。
成员内部类
成员内部类是最普通的内部类,它的定义为位于另一个类的内部,形如下面的形式:class Circle { double radius = 0; public Circle(double radius) { this.radius = radius; } class Draw { //成员内部类 public void drawSahpe() { System.out.println("drawshape"); } } }
这样看起来,类Draw像是类Circle的一个成员,Circle称为外部类。成员内部类可以无条件访问外部类的所有成员属性和成员方法(包括private成员和静态成员)。虽然成员内部类可以无条件地访问外部类的成员,而外部类想访问成员内部类的成员却不是这么随心所欲了。在外部类中如果要访问成员内部类的成员,必须先创建一个成员内部类的对象,再通过指向这个对象的引用来访问
即成员内部类是依附外部类而存在的,也就是说,如果要创建成员内部类的对象,前提是必须存在一个外部类的对象。
局部内部类
局部内部类是定义在一个方法或者一个作用域里面的类,它和成员内部类的区别在于局部内部类的访问仅限于方法内或者该作用域内。class People{ public People() { } } class Man{ public Man(){ } public People getWoman(){ class Woman extends People{ //局部内部类 int age =0; } return new Woman(); } }
注意: 局部内部类就像是方法里面的一个局部变量一样,是不能有 public、protected、private 以及 static 修饰符的。
匿名内部类
匿名内部类应该是平时我们编写代码时用得最多的class Outer{ void show() { System.out.println("run in Outer"); } } public class Demo { public static void main(String args[]) { Outer ot=new Outer(){ void show() { System.out.println("run in Inner"); } }; ot.show();//run in Inner } }
本质:其实是继承该类或者实现接口的子类匿名对象
- 匿名内部类是局部内部类的更深入一步。
- 匿名内部类的前提是存在一个类或者接口,且匿名内部类是写在方法中的。
- 只针对重写一个方法时使用,需要重写多个方法时不建议使用
静态内部类
静态内部类是不需要依赖于外部类的,这点和类的静态成员属性有点类似,并且它不能使用外部类的非static成员变量或者方法
public class Test {
public static void main(String[] args) {
Outter.Inner inner = new Outter.Inner(); //不需要外部类的实例!!!即不依赖于外部类
}
}
class Outter {
public Outter() {
}
static class Inner { //只能访问外部类的静态成员和方法哦!!!
public Inner() {
}
}
}
本作品采用《CC 协议》,转载必须注明作者和本文链接