专注Java教育14年 全国咨询/投诉热线:400-8080-105
动力节点LOGO图
始于2009,口口相传的Java黄埔军校
首页 hot资讯 final修饰符用法详解

final修饰符用法详解

更新时间:2020-10-27 17:48:11 来源:动力节点 浏览1627次

final修饰符一直是Java基础知识中非常重要的考点,final关键字可以用来修饰类、变量、方法。final变量不能重新赋值,子类不能覆盖父类的final方法,final类不能有子类。这些都是非常基础的考点,但是也是非常重要的内容,不容忽视。


1.final修饰成员变量

(1)final修饰的成员变量一旦赋值后,不能被重新赋值。

(2)final修饰的实例Field,要么在定义该Field的时候指定初始值,要么在普通初始化块或构造器中指定初始值。但是如果在普通初始化块中为某个实例Field指定了初始值,则不能再在构造器中指定初始值。

(3)final修饰的类Field,要么在定义该Field的时候指定初始值,要么在静态代码块中定义初始值。

(4)如果在构造器或初始化块中对final成员变量进行初始化,则不要在初始化之前就访问该成员的值。

package cn.lsl;

public class FinalTest {

final int a = 5; //直接赋值

final String str; //普通代码块中赋值

{

str = "zhangsan";

}

final int b; //构造器中赋值

public FinalTest(){

b = 7;

}

final static int c = 8; //直接赋值

final static int d; //静态代码块中赋值

static{

d = 9;

}

//如果在构造器或初始化块中对final成员变量进行初始化,则不要在初始化之前就访问该成员的值。

final int age;

{

//System.out.println(age);

age = 22;

System.out.println(22);

}

}


2.final修饰局部变量

(1)系统不会对局部变量进行初始化,布局变量必须要显示的初始化。所以使用final修饰的局部变量,既可以在定义的时候指定默认值,也可以不指定默认值。

(2)final修饰形参的时候,不能为该形参赋值。


3.final修饰基本数据类型变量和修饰引用类型变量的区别

使用final修饰基本类型的变量,一旦对该变量赋值之后,就不能重新赋值了。但是对于引用类型变量,他保存的只是引用,final只能保证引用类型变量所引用的地址不改变,但不保证这个对象不改变,这个对象完全可以发生改变。

final修饰的引用类型变量不能被重新赋值,但是可以改变引用变量所引用对象的内容。


4.final的“宏变量”

(1)final修饰符的一个重要用途就是“宏变量”。当定义final变量时就该为该变量指定了初始值,而且该初始值可以在编译时就确定下来,那么这个final变量本质上就是一个“宏变量”,编译器会把程序中

所有用到该变量的地方直接替换成该变量的值。

package cn.lsl;

public class FinalTest {

public static void main(String[] args){

final String name = "小明" + 22.0;

final String name1 = "小明" + String.valueOf(22.0);

System.out.println(name == "小明22.0");

System.out.println(name1 == "小明22.0");

}

}

final String name1 = "小明" + String.valueOf(22.0);中调用了String类的方法,因此编译器无法再编译的时候确定name1的值,所以name1不会被当成“宏变量”。


5.final修饰方法

用final修饰的方法不能被重写。用final修饰的类不能有子类。

因为重写的前提是子类可以从父类中继承此方法,如果父类中final修饰的方法同时访问控制权限为private,

将会导致子类中不能直接继承到此方法,因此,此时可以在子类中定义相同的方法名和参数,此时不再产生重写与final的矛盾,而是

在子类中重新定义了新的方法。


6.不可变类

不可变类是指创建该类的实例后,该实例的Field是不可改变的。

如果创建自定义的不可变类,应该遵循如下规则

(1)使用private和final修饰符来修饰该类的Field。

(2)提供带参数的构造器,用于传入参数来初始化类里的Field。

(3)仅为该类的Field提供getter方法,不要为该类的Field提供setter方法。

(4)如果有必要,重写Object类的hashCode和equals方法。

package cn.lsl;

public class Address {

private final String detail;

private final String postCode;

public Address() {

this.detail = "";

this.postCode = "";

}

public Address(String detail, String postCode) {

this.detail = detail;

this.postCode = postCode;

}

public String getDetail() {

return detail;

}

public String getPostCode() {

return postCode;

}

public boolean equals(Object obj){

if(this == obj){

return true;

}

if(obj !=null && obj.getClass() == Address.class){

Address ad = (Address)obj;

if(this.getDetail().equals(ad.getDetail()) && this.getPostCode().equals(ad.getPostCode())){

return true;

}

}

return false;

}

public int hashCode(){

return detail.hashCode() + postCode.hashCode() * 31;

}

}

因为final修饰引用类型变量时,表示这个引用变量不可重新被赋值,但引用类型变量所指向的对象依然可被改变。所以在创建不可变类的时候,如果包含的Field类型是可变的,那么这个不可变类就创建失败了。


Final修饰符作为Java基础中的重点内容,延伸出来的知识和考点还有很多,本文也只是总结了一部分比较重要的内容,想要全方位学习final修饰符的后续知识,可以观看本站的Java基础教程,快速熟练掌握final修饰符的全部用法。


提交申请后,顾问老师会电话与您沟通安排学习

免费课程推荐 >>
技术文档推荐 >>