多态:不同类的对象对同一消息作出不同的响应。
存在的条件:
1.继承关系 2. 子类重写父类方法 3.父类引用指向子类对象
不存在多态的情况:
1、static方法,因为被static修饰的方法是属于类的,而不是属于实例的
2、final方法,因为被final修饰的方法无法被子类重写
3、private方法和protected方法,前者是因为被private修饰的方法对子类不可见,后者是因为尽管被protected修饰的方法可以被子类见到,也可以被子类重写,但是它是无法被外部所引用的,一个不能被外部引用的方法,怎么能谈多态呢
final 关键字
作用:
1.被final修饰的类不可以被继承
2.被final修饰的方法不可以被重写
3.被final修饰不可变的是变量的引用,而不是引用指向的内容,引用指向的内容是可以改变的
4.被final修饰的方法,JVM会尝试为之寻求内联,这对于提升Java的效率是非常重要的。因此,假如能确定方法不会被继承,那么尽量将方法定义为final的,具体参见运行期优化技术的方法内联部分
5.被final修饰的常量,在编译阶段会存入调用类的常量池中,具体参见类加载机制最后部分和Java内存区域
static 关键字
1.被static修饰的变量属于类变量,可以通过类名.变量名直接引用,而不需要new出一个类来
2.被static修饰的方法属于类方法,可以通过类名.方法名直接引用,而不需要new出一个类来
执行原理:
静态资源属于类,但是是独立于类存在的。从JVM的类加载机制的角度讲,静态资源是类初始化的时候加载的,而非静态资源是类new的时候加载的。类的初始化早于类的new,比如Class.forName(“xxx”)方法,就是初始化了一个类,但是并没有new它,只是加载这个类的静态资源罢了。所以对于静态资源来说,它是不可能知道一个类中有哪些非静态资源的;但是对于非静态资源来说就不一样了,由于它是new出来之后产生的,因此属于类的这些东西它都能认识
常见Q:
1、静态方法能不能引用非静态资源?不能,new的时候才会产生的东西,对于初始化后就存在的静态资源来说,根本不认识它。
2、静态方法里面能不能引用静态资源?可以,因为都是类初始化的时候加载的,大家相互都认识。
3、非静态方法里面能不能引用静态资源?可以,非静态方法就是实例方法,那是new之后才产生的,那么属于类的内容它都认识。
静态块里面的代码只执行一次,且只在初始化类的时候执行。
静态资源的加载顺序是严格按照静态资源的定义顺序来加载的。
静态代码块对于定义在它之后的静态变量,可以赋值,但是不能访问。
静态代码块是严格按照父类静态代码块->子类静态代码块的顺序加载的,且只加载一次。
static修饰类
这个用得相对比前面的用法少多了,static一般情况下来说是不可以修饰类的,如果static要修饰一个类,说明这个类是一个静态内部类(注意static只能修饰一个内部类),也就是匿名内部类。像线程池ThreadPoolExecutor中的四种拒绝机制CallerRunsPolicy、AbortPolicy、DiscardPolicy、DiscardOldestPolicy就是静态内部类。
import static
这个比较冷门,基本很少看见有地方用,使用JUnit可能会用到,写assert的时候会方便些。import static是JDK1.5之后的新特性,这两个关键字连用可以指定导入某个类中的指定静态资源,并且不需要使用类名.资源名,可以直接使用资源名。注意一下,import static必须这么写,而不能写成static import。