Java 中的 final 修饰符
最流行的面试题之一,网上有很多概念,每次准备面试都要背上一遍,今次写作代码,希望帮助大家了解更深一点,注意,为了让大家直观的感受一下,代码有些地方报错,相应地方有注释,不自己运行也可以
import java.util.HashMap;
import java.util.Map; /** * 首先,final 修饰的类不可被继承 * 如果你写一个类去继承就会出现如下图1所示的错误提示 */ public final class FinalTest1 { /** * 网上有错误说法,说final修饰的方法不能被重载,以下代码可证实是错误的 * final修饰的类不能被继承,修饰的方法不能被重写,其实是同理的 */ public final static void lalala(){ System.out.println("啦啦啦"); } public static void lalala(String lalala){ //此处不报错 System.out.println("啦啦啦"); } public static void main(String[] args) { /** * final 修饰的变量不可修改,值得是引用地址不可修改 * 对于基本变量来说,就是值不能修改 * 对于引用型变量来说,是引用地址不可修改,但是值是可以修改的 * 以下拿 int String StringBuffer Map 做例子 */ // 基本变量值不可修改 final int a = 5; a = 6; //此处报错 // String 类是引用变量,final 修饰后重新给它赋一个String变量是不行的 // String 没有提供改变自身变量值的方法,所以可以拿 StringBuffer 举例 final String str1 = "lalala"; str1 = "hehehe"; //此处报错 final StringBuffer str = new StringBuffer("hehehe"); // 这里引用地址变了,所以不可以 str = new StringBuffer("lalala"); //此处报错 // 这里只是对值进行了修改 str.append("lalala"); //此处不报错 Map<String, String> map = new HashMap<String, String>(); map.put("name", "sophia"); map.put("age", "18"); map.put("time", "20180620"); final Map<String, String> map2 = map; //此处改变值是可以的 map2.put("hobby", "sing"); //此处不报错 //此处赋值是改变了地址的,所以不可以 map2 = map; //此处报错 } }
下面,把 FinalTest1 类取消 final 修饰
/** * 首先,final 修饰的类不可被继承 * 如果你写一个类去继承就会出现如下图1所示的错误提示 */ public class FinalTest1 { /** * 网上有错误说法,说final修饰的方法不能被重载,以下代码可证实是错误的 * final修饰的类不能被继承,修饰的方法不能被重写,其实是同理的 */ public final static void lalala(){ System.out.println("啦啦啦"); } public static void lalala(String lalala){ System.out.println("啦啦啦"); } }
然后写一个 FinalTest3 的类去继承 FinalTest1 类,并重写其中的方法
结果很明显,第一个在父类中用 final 修饰的方法是不可以被重写的,相反,没有 final 修饰的方法是可以被重写的。
public class FinalTest3 extends FinalTest1{ public final static void lalala(){ //此行报错 System.out.println("呵呵呵"); } public final static void lalala(String string){ //此行不报错 System.out.println("呵呵呵"); } }