1. final
- 对于基本类型,final 使数值不变;
- 对于引用类型,final 使引用不变,也就不能引用其它对象,但是被引用的对象本身是可以修改的。
可用来修饰类、类的成员、局部变量:
- final修饰的类——不可以被继承,但可以继承其他类
- final修饰的方法——不可以被重写。但若父类中没有final修饰的方法,子类重写后,可加final修饰
- private 方法隐式地被指定为 final
- final修饰的变量——成为常量,只可被赋值一次。
- 变量为:引用类型——变量值为对象的地址,地址值不可更改,但是地址内的对象属性值可以更改
- 变量为:成员变量——需在创建的时候赋值,否则报错。(当未显式赋值时,多个构造方法内部均需为其赋值)。
2. static
一般用来修饰类中的成员。
被static修饰的成员属于这个类,不属于这个类的某个实例对象,可通过类名直接访问。
多个对象共享一个static成员变量。
(实例变量:每创建一个实例就会产生一个实例变量,它与该实例同生共死。)
静态内容优先于对象存在,只能访问静态,不能使用this/super(没有对象,则无this)。
同一个类中,静态成员只能访问静态成员方法/变量。
main()为静态方法,仅仅为程序入口,它不属于任何一个对象,可以定义在任何类中。
2.1 静态变量
又称为类变量,也就是说这个变量属于类的。
静态变量属于类,只要静态变量所在的类被加载,这个静态变量就会被分配空间,在内存中只有一份,所有对象共享这个静态变量。
实例变量属于对象,只有对象被创建之后,实例变量才会被分配空间,才能被使用,它在内存中有多个复制。
使用有二种方式: 一个是类名.静态变量,还有一种是对象.静态变量。
特别注意:Java中不能在方法体中定义静态变量(无论该方法是静态的或是非静态的)。
2.2 静态方法
静态方法在类加载的时候就存在了,它不依赖于任何实例。
静态方法必须有实现,也就是说它不能是抽象方法(abstract) 。
只能访问所属类的静态字段和静态方法,方法中不能有 this 和 super 关键字。
重要用途:实现单例模式。
单例模式的特点:该类只有一个实例。需要求:
- 隐藏类的构造函数(构造函数声明为private);
- 提供一个创建对象的方法,通过该类的方法来获取类的对象(将这个方法声明为static)。
public class Singleton {
private static Singleton instance = null;
private Singleton(){};
public static Singleton getInstance(){
if(instance == null){
instance = new Singleton();
}
return instance;
}
}
2.3 静态常量
public static final 修饰
此变量名全部用大写,多个单词使用下划线连接
public static final COMPANY_NAME="HH"。
引用:类名.COMPANY_NAME;
(接口中的成员变量时静态常量,可用接口名直接访问)
工具类中的方法大多是静态的。
2.4 静态语句块
静态语句块在类初始化时运行一次。
public class A {
static {
System.out.println("123");
}
public static void main(String[] args) {
A a1 = new A();
A a2 = new A();
}
}
2.5 静态内部类
只有内部类才能被定义为static。
非静态内部类依赖于外部类的实例,而静态内部类不需要。
静态内部类不能访问外部类的非静态的变量和方法
public class OuterClass {
class InnerClass {
public void print(){
System.out.println("innerClass");
}
}
static class StaticInnerClass {
public void print(){
System.out.println("staticInnerClass");
}
}
public static void main(String[] args) {
//InnerClass innerClass = new InnerClass(); // ERROR:'OuterClass.this' cannot be referenced from a static context
OuterClass outerClass = new OuterClass();
InnerClass innerClass = outerClass.new InnerClass();
innerClass.print();
StaticInnerClass staticInnerClass = new StaticInnerClass();
//OuterClass.StaticInnerClass in = new OuterClass.StaticInnerClass();//OK
staticInnerClass.print();
}
}
输出:
innerClass
staticInnerClass
2.6 优点:
对对象的共享数据提供单份存储,节省空间
可直接由类名调用,不用在堆内创建对象。
2.7 缺点
访问出现局限性(只可访问静态)。
3. instanceof
用法:boolean b=对象 instanceof 数据类型;
Person p1=new Student();
boolean flag1=p1 instanceof Student;//true
boolean falg2=p1 instanceof Person;//false
instanceof通过返回一个布尔值来指出,这个对象是否是:
- 这个特定类或者
- 它的子类的一个实例或
- 当前接口的实现类
的实例。
注意:如果对象A为null,则返回false。
4. 向上转型
自动
将子类对象赋给一个父类引用(多态)
提高了代码的扩展性
只使用父类共性的内容,无法使用子类特有的功能,要不编译不通过。
5. 向下转型
强制
一个已经向上转型的子类对象可以使用强制类型转换的格式,将父类引用专为子类引用。
在需使用子类特有功能时
易发生ClassCastException异常,所以转换前需要进行类型判断
if(! a instanceof Dog){...}
Person p=new Student();
Student stu=(Student) p;
如果是直接创建的父类对象,无法向下转型
6. 初始化
原则:
- 静态对象(变量)优先于非静态对象(变量)初始化,其中静态对象(变量)只初始化一次,非静态对象(变量)可能初始化很多次;
- 父类有限域子类进行初始化;
- 按照成员变量的定义顺序进行初始化,即使变量定义散布于方法定义之中,它们依然在任何方法(包括构造函数)被调用之前先初始化
初始化执行顺序:
- 父类静态变量
- 父类静态代码块
- 子类静态变量
- 子类静态代码块
- 父类非静态变量
- 父类非静态代码块
- 父类构造函数
- 子类非静态变量
- 子类非静态代码块
- 子类构造函数