final关键字
final是Java中的一个关键字,final又名终结器,可以用来修饰变量,方法,类。
什么是final 变量/ 方法 / 类?
简单而言,变量被final修饰,即为final变量,方法被final修饰即为final方法,类被final修饰即为final类。
final修饰类------------final修饰的类不能被继承
final class Animal //final修饰
{
public Animal()
{
System.out.println("动物类的无参构造");
}
}
class Cat extends Animal //报错,原因final修饰的额类不能被继承
{
}
public class Test
{
public static void main(String[] args)
{
System.out.println("hello");
}
}
//*******************************分隔符***************************************
class Animal //去掉final
{
public Animal()
{
System.out.println("动物类的无参构造");
}
}
class Cat extends Animal //正确
{
}
public class Test
{
public static void main(String[] args)
{
System.out.println("hello");
}
}
注:final不能和abstract同时修饰类因为final修饰的类不能被继承
final修饰方法--------------final修饰的方法不能被覆写(重写)
class Animal
{
public Animal()
{
System.out.println("动物类的无参构造");
}
public final void fun() //被final修饰的普通方法
{
System.out.println("动物类的普通方法");
}
}
class Cat extends Animal
{
public final void fun() //报错 Cannot override the final method from Animal 即不能覆写
{
System.out.println("小猫类的普通方法");
}
}
public class Test
{
public static void main(String[] args)
{
System.out.println("hello");
}
}
//*************************************分隔符********************************************
class Animal
{
public Animal()
{
System.out.println("动物类的无参构造");
}
public void fun() //没有final修饰
{
System.out.println("动物类的普通方法");
}
}
class Cat extends Animal
{
public void fun() //正确,可以覆写。
{
System.out.println("小猫类的普通方法");
}
}
public class Test
{
public static void main(String[] args)
{
System.out.println("hello");
}
}
final修饰方法的作用
- 将方法锁定,以防止其它类通过继承来修改该方法的含义。
- 提升效率,final修饰的方法,会内嵌调用,忽略执行方法调用机制,而采取常规代码插入方法(将自变量压入堆栈;跳至方法代码并执行它;跳回来;清除堆栈自变量;最后对返回值进行处理)。但方法体太过庞大则不会有任何性能提升。简单而言,final修饰的方法速度比非final修饰的方法快。
- 总结:只有在方法的代码量非常少,或者想明确禁止方法被覆盖的时候,可以将一个方法设为final。
final修饰变量
- final修饰普通变量---------普通变量的值不可改变。
public class Test
{
public static void main(String[] args)
{
final int a = 2;
a++; //报错 The final local variable a cannot be assigned.即内容不可改变
}
}
- final修饰引用变量---------引用变量的引用不可改变,但引用变量的内容可以改变。
class Person
{
int age;
public Person(int age)
{
this.age = age;
}
}
public class Test
{
public static void main(String[] args)
{
final Person p1 = new Person(12);
Person p2 = new Person(12);
p1 = p2; //报错 The final local variable p1 cannot be assigned.p1被final修饰,不能指向其它堆内存
}
}
//****************************************分隔符***********************************************
class Person
{
int age; //没有被private修饰可以直接对象访问
public Person(int age)
{
this.age = age;
}
}
public class Test
{
public static void main(String[] args)
{
final Person p1 = new Person(12);
p1.age = 22; //正确
System.out.println(p1.age);
}
}
空白final
Java 1.1允许我们创建“空白final”,它们属于一些特殊的字段。尽管被声明成final,但却未得到一个初始值。无论在哪种情况下,空白final都必须在实际使用前得到正确的初始化。而且编译器会主动保证这一规定得以贯彻。然而,对于final关键字的各种应用,空白final具有最大的灵活性。
class A
{
final int i ; //空白final
public A (Integer i)
{
this.i = i;
}
}
public class Test
{
public static void main(String[] args)
{
A a = new A(10);
System.out.println(a.i);
}
}
确保final字段在使用前获得正确的初始化:
- 定义字段时使用一个表达 式,
- 在每个构造器中
经典笔试题
一.四个语句中哪些是正确的?哪些是错误的?
byte b1 = 0,b2 = 0,b3 = 0,b6 = 0,b8 = 0;
final byte b4=4,b5=6,b7=9;
public void test()
{
b3=(b1+b2); /*语句1*/
b6=b4+b5; /*语句2*/
b8=(b1+b4); /*语句3*/
b7=(b2+b5); /*语句4*/
}
答案:正确: 语句2. 错误:语句1,3,4.
解析:在Java中,小于等于int类型的两个数相加结果会自动转为int类型。但被final修饰后其类型不会发生变化。
- 语句一:byte +byte 结果为int,赋给byte因此错误。
- 语句二:被final修饰的byte + byte 结果仍为byte,赋给byte没有问题。
- 语句三:同语句一。
- 语句四:同语句一。
二.输出是啥?
public class Test
{
public static void main(String[] args)
{
String str1 = "helloworld";
String str2 = "hello";
final String str3 = "hello";
String str4 = str2 + "world";
String str5 = str3 + "world";
System.out.println(str1 == str4);
System.out.println(str1 == str5);
}
}
答案:false , true。