外观
final关键字
final关键字
可以修饰的东西:类、方法、变量(类不可被继承、方法不可被重载、成员变量不可被再次赋值)
1.修饰类时:类不能被继承(会隐式给类的方法添加final修饰符)
// 报错,final修饰的类不可继承
public class FinalSub extends FinalClass {
}
final class FinalClass{
}
public class FinalSub extends FinalTest {
FinalTest finalTest = new FinalTest();
// 报错,被final修饰的方法不可重写
public void test() {
}
public static void main(String[] args) {
System.out.println(System.currentTimeMillis());
}
}
作用:防止篡改(重写某些方法)
2.final修饰方法时:方法不可被重写
作用:1.防止重写(防止改变实现)
2.效率问题:当方法体比较短时,final修饰的方法调用时相当于把方法体移动到调用处
// final修饰的方法
public final static void test1() {
System.out.println("final test1()");
}
// 普通方法
public static void test2() {
System.out.println("test2()");
}
public static void main(String[] args) {
System.out.println("非final的方法");
// 获取jvm的启动时间
long start = System.currentTimeMillis();
test2();
long end = System.currentTimeMillis();
System.out.println();
System.out.println(end-start);
System.out.println("final的方法");
start = System.currentTimeMillis();
test1();
end = System.currentTimeMillis();
System.out.println();
System.out.println(end-start);
}
Tip:
System.currentTimeMillis()// 获取jvm启动时间(毫秒)
3.final修饰变量:变量为不可变变量
可修饰变量类型:成员变量、局部变量、形参、块变量
final修饰的变量的初始化方式:
1.定义时初始化
private final int i = 0; // 定义时对不可变变量初始化
2.代码块初始化
private final int a;
{
a = 4; // 普通代码块对不可变变量初始化
}
3.构造方法初始化
public class FinalTest {
private final int j;
public FinalTest() {
j = 3; // 构造方法对不可变变量初始化
}
}
final+static修饰的变量(常量)的初始化:
1.定义时初始化
private static final int b = 0; // 定义时对常量初始化
2.static代码块初始化
private static final int c;
static {
c = 5; // static代码块对常量初始化
}
作用:
1.限制变量初始化后只能读取,不会被无意间修改
2.效率,促使变量在编译过程被优化从而提高效率
Tip:
javap -c -l 类名.class// 反编译class文件
final修饰引用类型的变量时只是限制不可改变对象的指向,而对象的内容仍然可以改变
abstract关键字
可以修饰的东西:修饰类表示该类是一个抽象类、修饰方法表示该方法是一个抽象方法(没有方法体)
注:abstract不可修饰变量只能修饰类和方法
1.修饰类:
抽象类和普通类的区别:
唯一区别:抽象类不可实例化
final和abstract不能同时出现(同时修饰一个方法或类)
抽象类可以有成员变量、构造方法、成员方法、代码块、内部类、注解
它的成员和普通类没有区别
2.修饰方法
抽象方法没有方法体
public abstract void test(); // 抽象方法没有方法体
一个不能被重写的方法坚决不能被抽象
抽象方法就是用来被重写的
abstract不能与final、static连用
abstract不可以与private连用,原因是private方法不能被继承,不能构成重写操作
抽象类中可以有普通方法
抽象方法必须在抽象类中,抽象方法没有实现,若实例化后将产生一个不能执行的方法,需要限制它不能实例化
public /*final*/ abstract class AbstractTest {// 抽象类不能被final修饰
// 抽象类可以有成员变量
private int test;
public int test1;
// public abstract int test1; abstract不能修饰变量
public abstract void test(); // 抽象方法没有方法体
// private abstract void test2(); abstract不能与private联用
// public static abstract void test3(); abstract不能与static联用
// public final abstract void test4(); abstract不能与final联用
public abstract void test5();
// 抽象类可以有普通成员方法
public void test1() {
System.out.println("test1()");
}
}
public class AbstractSub extends AbstractTest {
@Override
// 重写抽象类的抽象方法
public void test() {
System.out.println("test()");
}
@Override
public void test5() {
System.out.println("test5()");
}
// abstract修饰的类的成员方法可以被子类调用
public void test7() {
// new AbstractSub().test1 = 1;
new AbstractSub().test1();
}
// 抽象方法只能在抽象类中
// public abstract void test6();
}
抽象类的作用:
1.定义规则规范
2.本身不能被实例化但表达了共同的能力
一个类如果继承了抽象方法:
1.重写抽象方法
2.自身继续抽象
自身不可实例化但是可以实例化它的非抽象子类
注:抽象类通常在设计阶段使用,用来规范开发