参考来源:https://mp.weixin.qq.com/s/FoQXksfXlTPvboWRMstvjA
说明:本文部分内容参考自上述文章,在上述文章的基础上做了一定的删减修改,如有侵权请联系删除。修饰类
用final修饰一个类时,这个类不能被继承final类中的成员变量可以根据需要设为final,但是final类中的所有成员方法都会被隐式地指定为final方法。 public final class Animal { public Animal(){ } } 开发中,尽量不要将类设计为final类,除非处于安全考虑或者保证该类一定不会被继承了。修饰方法
final修饰的方法不能被覆盖类的private方法会隐式地被指定为final方法修饰变量
final修饰变量时,如果是基本数据类型的变量,则数值一旦在初始化之后便不能更改如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象。 如图:上述代码对a和o的重新赋值都被提示出错。被final修饰的引用变量指向的对象内容可变
public class Aniaml { public static void main(String[] args) { final MyAnimal myAnimal = new MyAnimal(); System.out.println(++myAnimal.i); //输出结果:1 } } class MyAnimal { public int i = 0; }上述例子说明:引用变量被final修饰之后,虽然不能再指向其他对象,但是它指向的对象的内容是可变的
final和static
static作用于成员变量表示只保存一份,final的作用是用来保证变量不可变。 public class Test { public static void main(String[] args) { MyClass myClass1 = new MyClass(); MyClass myClass2 = new MyClass(); System.out.println(myClass1.i); System.out.println(myClass1.j); System.out.println(myClass2.i); System.out.println(myClass2.j); } } class MyClass { public final double i = Math.random(); public static double j = Math.random(); }上述例子:每次输出的j值都相同,输出的i值不同
匿名内部类中使用的外部局部变量只能是final变量 final参数问题
public class Test { public static void main(String[] args) { MyAniaml myAniaml = new MyAniaml (); int i = 0; myAniaml.changeValue(i); System.out.println(i); } } class MyAniaml { void changeValue(final int i) { i++; //该行会报错,提示:不能对i进行赋值 } }上面这段代码好像让人觉得用final修饰之后,就不能在方法中更改变量i的值了。殊不知,方法changeValue和main方法中的变量i根本就不是一个变量,因为java参数传递采用的是值传递,对于基本类型的变量,相当于直接将变量进行了拷贝。所以即使没有final修饰的情况下,在方法内部改变了变量i的值也不会影响方法外的i。
public class Test { public static void main(String[] args) { MyClass myClass = new MyClass(); StringBuffer buffer = new StringBuffer("hello"); myClass.changeValue(buffer); System.out.println(buffer.toString()); } }运行这段代码就会发现输出结果为 helloworld。很显然,用final进行修饰并没有阻止在changeValue中改变buffer指向的对象的内容。有人说假如把final去掉了,万一在changeValue中让buffer指向了其他对象怎么办。有这种想法的朋友可以自己动手写代码试一下这样的结果是什么,如果把final去掉了,然后在changeValue中让buffer指向了其他对象,也不会影响到main方法中的buffer,原因在于java采用的是值传递,对于引用变量,传递的是引用的值,也就是说让实参和形参同时指向了同一个对象,因此让形参重新指向另一个对象对实参并没有任何影响。
