Java中的关键字final
final可以修饰类、变量、方法。
(1)类
当final修饰类的时候,该类为最终类,不能被继承。
注:类为final类,类中的方法默认为final方法(必须为final),类中的变量默认我final变量(必须为final)。
(2)方法
final修饰方法。当父类的方法为final时候,子类不能覆盖父类的同名方法。
如下代码:
public class AnimalDemo {
public static void main(String[] args) {
Dog d1 =new Dog();
d1.getClass();
}
}
class Animal{
private String name="aaa";
public final void getName(){ //public方法被子类继承
}
}
class Dog extends Animal{
public void getName(){ //此处会报错,因为Dog会从父类继承getName()方法,而且方法为final不能被覆盖
}
}
但是,如下代码不会报错:
public class AnimalDemo {
public static void main(String[] args) {
Dog d1 =new Dog();
d1.getClass();
}
}
class Animal{
private String name="aaa";
private final void getName(){ //private 方法不被子类继承
}
}
class Dog extends Animal{
public void getName(){ //此处不会报错,因为父类的getName()是私有的,不被子类继承.所以,子类定义不会报错
}
}
说明:
(1)当父类的方法为public final时候,子类(继承了方法,但是方法是最终方法)不能覆盖父类的同名方法。(父类的方法可以被继承,不能被覆盖)
(2)当父类的方法为private final时候,子类(继承不了该方法)可以定义和父类同名的方法。(父类的方法不被继承)
(3)变量
final修饰变量的时候,变量的值一旦被赋值后,就不可更改。
如:(一旦赋值,就再也不能修改了)
public class AnimalDemo {
public static void main(String[] args) {
Animal a1=new Animal("ccc");
System.out.println(a1.getName());
}
}
class Animal{
private final String name="aaa"; // 定义的一个final变量(即常量),已赋值
public Animal(){ // 在无参构造函数里必须赋值,错误,不能更改
//name="ddd";
}
public Animal(String name){ // 在有参构造函数里必须赋值,错误,不能更改
//this.name=name;
}
public String getName(){
return name;
}
}
也可以延迟到构造函数里进行赋值,但是,一旦赋值,也不能更改,所以不能调用setName()
public class AnimalDemo {
public static void main(String[] args) {
Animal a1=new Animal("ccc");
System.out.println(a1.getName());
}
}
class Animal{
private final String name; // 定义的一个final变量(即常量),未赋值
public Animal(){ // 在无参构造函数里必须赋值
name="ddd";
}
public Animal(String name){ // 在有参构造函数里必须赋值
this.name=name;
}
public String getName(){
return name;
}
public void setName(){ //常量不能被更改,错误,已经赋值不能更改
name="eee";
}
}
注意:
(1)定义一个final变量时候,立即赋值,则之后都不能更改。
(2)定义一个final变量时候,延迟到构造函数里赋值,赋值后也不能更改。(定义之后不立即赋值,延迟到构造赋值)
有一个问题?:
public class AnimalDemo {
public static void main(String[] args) {
System.out.println("hello"=="hello");
final String s1="he";
System.out.println("hello"==s1+"llo"); //true, 为什么是true呢
String s2="he";
System.out.println("hello"==s2+"llo"); //false, 为什么是false呢
}
}
final修饰的变量是常量。所以在编译期间,s1+"llo"被优化为"hello"。
但是为什么 “hello”==s2+"llo" 是错误的呢?