13.final关键字

finial关键字

1.final修饰的类无法被继承

public class FinalTest01{
	public static void main(String[] args){
		
	}
}

final class A{//A类被final修饰
	
}
//错误: 无法从最终A进行继承
class B extends A{
	
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2yTboRwo-1618583294368)(C:\Users\15195891836\AppData\Roaming\Typora\typora-user-images\image-20210415104736101.png)]

2.final修饰的方法无法被覆盖

public class FinalTest02{
	public static void main(String[] args){
		
	}
}

class A{
	public final void f(){
		
	}
}

class B extends A{
	//错误: B中的f()无法覆盖A中的f()
	public void f(){
		
	}
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-E5jpQ5vv-1618583294373)(C:\Users\15195891836\AppData\Roaming\Typora\typora-user-images\image-20210415105051365.png)]

3.final修饰的变量只能赋一次值

public class FinalTest03{
	//final修饰的变量只能赋值一次
	public static void main(String[] args){
		final int i = 1;
		//错误: 无法为最终变量i分配值
		i = 2;
	}
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qh03U5LR-1618583294374)(C:\Users\15195891836\AppData\Roaming\Typora\typora-user-images\image-20210415105358966.png)]

4.final修饰的引用

public class FinalTest04{
	public static void main(String[] args){
		//final 修饰引用
		final User u = new User("张三");
		//u 指向另一个对象
		u = new User("李四");
	}
}
class User{
	String name;
	public User(){}
	public User(String name){
		this.name = name;
	}
}


final修饰的变量只能赋一次值,引用也是变量,指向一个对象后,就不能再重新指向其他对象

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-736uXpTV-1618583294376)(C:\Users\15195891836\AppData\Roaming\Typora\typora-user-images\image-20210415110556124.png)]

内存图示意:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SNRsgsbg-1618583294378)(C:\Users\15195891836\AppData\Roaming\Typora\typora-user-images\image-20210415111850533.png)]

由上面可知,final修饰的引用指向的对象只有当方法执行完毕,局部变量u释放时,垃圾回收器才会回收该对象。

5.final修饰实例变量

思考:实例变量什么时候初始化?

在调用构造方法时,构造方法内部隐含了赋默认值的代码:

所以实例变量在调用构造方法时完成了初始化(new对象的时候)

class A{
    String name;
    int age;
    public A(){
        //this.name = null;
        //this.age = 0;
    }
}

因此,一般的实例变量不进行手动赋值时,系统会赋默认值,但是final修饰的实例变量必须进行手动赋值,并且只能赋一次值!

public class FinalTest05{
	public static void main(String[] args){
	
	}
}
class User{
    //final修饰的实例变量没初始化
    //错误: 变量 age 未在默认构造器中初始化
	final int age;

}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qFEh5Z7u-1618583294380)(C:\Users\15195891836\AppData\Roaming\Typora\typora-user-images\image-20210415112928201.png)]

实际上,此时针对finala修饰的实例变量,构造器不再进行默认初始化,必须手动初始化:

要么定义时初始化,要么在构造方法中初始化

1.声明变量时初始化

public class FinalTest05{
	public static void main(String[] args){
		
	}
}
class User{
	final int age = 10;
	public User(){	
	}
}

2.构造方法中初始化

public class FinalTest05{
	public static void main(String[] args){
		
	}
}
class User{
	final int age ;
	public User(){
		this.age = 10;
	}
	public User(int age){
		this.age = age;
	}

}

6.常量

final修饰的实例变量一般和static联合使用,称为常量

思考:下面的代码定义的实例变量有什么缺点?

public class FinalTest06{
	public static void main(String[] args){
		
	}
}
class Chinese{
	String name;
	String sex;
	//中国人国籍都是中国
	String country;
}

实际上Chinese类型的对象国籍属性都是中国,只需要定义一次即可,不需要重复初始化(final)。若定义为一般的实例变量,会在堆内存中占用内存,造成浪费(static)。

public class FinalTest06{
	public static void main(String[] args){
		
	}
}
class Chinese{
	String name;
	String sex;
	//中国人国籍都是中国
	public static final String country = "中国";
}

final修饰的实例变量必须初始化,且只能赋值一次。就意味着后续不能修改也无法修改。所以一般常量定义为public,不需要私有化。

注意:

常量的变量名一般全部大写,单词之间用下划线分开

public static final PI = 3.1415926;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值