static&final关键字、内部类
1.static关键字
static
是一个修饰符,可以修饰类(内部类),修饰方法,修饰属性,修饰初始化块,被static
修饰的元素则与对象无关,与类直接相关,访问元素时只需要通过类名访问即可(无需创建对象)
类变量
也称静态变量,变量的数据值由类进行控制,是一个所有对象 看到都是相同值,语法
static 数据类型 变量名
类变量的初始化时间实在类加载时就初始化,而非创建对象时
类变量,成员变量,局部变量生命周期
- 当对象中的成员方法执行完毕时,方法内部的局部变量会被回收
- 当对象使用完毕时,GC清理对象,同时将对象中申请的成员变量空间清理
- 最后当jvm结束时,才清理
static
变量
类方法
静态方法,使用static修饰成员方法,被修饰的方法和被修饰的属性一样无需创建对象调用,语法:
访问修饰符 static 返回值 方法名(参数列表){
//执行体
}
调用类方法时分为两种情况
- 在当前类直接调用,直接使用
方法名()
调用- 在其他类中访问当前类静态方法,
类名称.方法名()
调用注意事项:
- 不能在静态方法中使用非静态的成员,除非通过对象访问(成员变量.成员方法)
- 不能在静态方法中使用
this
关键字因为
this
代表的是当前对象,而static
是类方法,类方法在类加载的时候就已经被加载了,这时候还是没有对象,因此这里不能用this
对于
static
的使用不能滥用,因为static
成员会常驻内存,只有JVM结束时才会销毁,所以会带来一定空间消耗影响程序的执行效率
初始化块与静态初始化块
初始化块
又称游离块,是一个没有名称的代码块,执行时间一般在创建对象执行构造器前执行,并且执行次数取决于对象创建次数
{
//初始化块
}
静态初始化
也称静态块,就是使用static
关键字对初始化进行修饰,一旦类加载就会执行静态块,并且,静态不会随着对象创建而反复执行,只会执行一次;
静态块一般作用于无论创建对象,只需要执行一行的需求
static{
Class.forName:("com.mysql.jdbc.Driver");
}
- 静态初始化块无论创建多少次,只会执行一次
- 初始化块会随对象的创建次数而执行对应次数
设计模式(单例模式)
在程序的运行过程中无论如何创建对象,始终只存在一个实例,这种模式称为单例模式;无论何时获得的对象永远是同一个对象
饿汉式
以空间换时间,后续需要实例直接掉方法即可
public class People{
private static People people = new People();
//构造器私有化,防止外加随意访问
private People(){
}
//提供一个static方法用于返回当前类对象
public static People newInstance(){
return people;
}
}
懒汉式
以时间换空间,类加载时不会创建对象,只有当调用方法时才会选择创建
public class User {
private static User user;
private User(){}
public static User newInstance(){
//当调用当前方法时,检查对象是否存在
//若不存在则创建
if(user == null){
user = new User();
}
return user;
}
}
2.final关键字
表示最终,不可改变的意思,是一个修饰符,可以修饰类、属性、方法局部变量
- 被final修饰的类不可以被继承
- 被final修饰的变量不可以被修改
- 被final修饰的方法不能被重写
- 被final修饰的局部变量可以被延长生命周期,不会随着方法的执行结束而清理,而是跟使用他的语句块生命周期一致(内部类)
3、内部类
在一个类中声明的其他java类,这些类也是嵌套类
成员内部类
类似成员变量、成员方法,与成员变量和成员方法同一级别
注意事项:
- 成员内部类与成员变量,成员方法统一级别
- 创建成员内部类需要由外部类对象完成
- 可以在内部类中直接访问外部类成员
- 多数时候的成员内部类都是private
- 创建内部类实例必须通过外部类的对象创建
局部内部类
类似局部变量,一般在一个方法或者语句块中出现,适用范围也只是在当前声明区域
注意事项:
- 局部内部类不能适用任何的访问修饰符,因为这个类的访问权限在方法上已经定义了
- 局部内部类中可以使用方法或者语句块中声明的局部变量,但是只能用,不能修改(该变量会自动标记为
final
,在java8以前需要手动声明)
静态内部类
与静态变量、静态方法的加载顺序是一致的,使用static修饰的成员内部类
注意事项:
- 静态内部类一般用于在一个类中缓存数据
匿名内部类
没有类名称的内部类,大多数时候,匿名内部类一般针对抽象类和接口使用(涉及到接口回调)
接口回调:就是使了此接口根本就不用调用接口中的方法,因为在接口中已经调用了此方法。
注意事项:
- 匿名内部类即没有名字的内部类
- 创建匿名内部类时就是在创建匿名内部类的对象
- 匿名内部类没有构造器,可以使用
初始化
块实现构造器的功能。
内部类访问当前对象问题
this
表示当前成员的对象;如果在内部类中直接使用this
,这时的this
表示内部类的对象,如果访问外部类的this
,则应该使用外部类的类名.this
内部类的好处
- 内部类提供了比方法更好的封装性
- 使用内部类可以解决外部类只能单继承的问题(内部类也可以继承其他的类)