前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >final关键字

final关键字

作者头像
Mister24
发布2018-05-14 10:56:58
8270
发布2018-05-14 10:56:58
举报
文章被收录于专栏:java初学java初学

final可以修饰非抽象类、非抽象类成员方法和变量。

(1)final类:不能被继承,没有子类,final类中的方法默认是final的;

(2)final方法:不能被子类的方法覆盖,但可以被继承;

(3)final成员变量:表示常量,只能被赋值一次,赋值后值不再改变;

(4)final不能用于修饰构造方法。

(父类的private成员方法是不能被子类方法覆盖的,因此private类型的方法默认是final的)

1.final类

final类不能被继承,因此final类的成员方法没有机会被覆盖,默认是final的,在设计类的时候,如果这个类不需要有子类,类的实现细节不允许变动,并且确定这个类不会再被扩展,可以将这个类设置为final类。

2.final方法

如果一个类不允许子类覆盖某个方法,可以将这个方法设置为final方法。

  将方法声明为final的原因主要有两个:

    ①将方法锁定:防止任何子类修改它的意义和实现;

    ②高效:编译器遇到调用final方法的时候,会转入内嵌机制,大大提高执行效率。

父类Test1.java

代码语言:javascript
复制
package EmployeeTest_4_2;

public class Test1 
{
	public static void main(String[] args)
	{
		
	}
	
	public void f1()
	{
		System.out.println("父类的f1");
	}
	
	public final void f2()
	{
		System.out.println("父类的f2");
	}
	
	public void f3()
	{
		System.out.println("父类的f3");
	}
	
	public void f4()
	{
		System.out.println("父类的f4");
	}
	
}

子类Test2.java

代码语言:javascript
复制
package EmployeeTest_4_2;

public class Test2 extends Test1
{
	public void f1()
	{
		System.out.println("父类的f1方法被覆盖!");
	}

	//这种声明f2的方法会报错,因为在Test1中已经将f2方法声明为final
//	public void f2()
//	{
//		System.out.println("父类的f2方法被覆盖!");
//	}
	
	public void f3()
	{
		System.out.println("父类的f3方法被覆盖!");
	}
	
	
	public static void main(String[] args)
	{
		Test2 t = new Test2();
		t.f1();
		t.f2();
		t.f3();
		t.f4();
	}

}

输出的结果为:

代码语言:javascript
复制
父类的f1方法被覆盖!
父类的f2
父类的f3方法被覆盖!
父类的f4

  由于父类中f2方法已经被声明为final,所以如果在子类Test2中重写f2方法的时候,会报错,这时候会提示将父类Test1中的f2方法声明为“非final”方法。

代码语言:javascript
复制
Exception in thread "main" java.lang.VerifyError: class EmployeeTest_4_2.Test2 overrides final method f2.()V
	at java.lang.ClassLoader.defineClass1(Native Method)
	at java.lang.ClassLoader.defineClass(Unknown Source)
	at java.security.SecureClassLoader.defineClass(Unknown Source)
	at java.net.URLClassLoader.defineClass(Unknown Source)
	at java.net.URLClassLoader.access$100(Unknown Source)
	at java.net.URLClassLoader$1.run(Unknown Source)
	at java.net.URLClassLoader$1.run(Unknown Source)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(Unknown Source)
	at java.lang.ClassLoader.loadClass(Unknown Source)
	at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
	at java.lang.ClassLoader.loadClass(Unknown Source)
	at sun.launcher.LauncherHelper.checkAndLoadMain(Unknown Source)

3.final变量

用final修饰的成员变量表示常量,值一旦给定就无法改变。

  总共可以修饰三种变量:静态变量、实例变量和局部变量。

  final变量定义的时候,可以先声明,而不给初值,这中变量也称为final空白,无论什么情况,编译器都确保空白final在使用之前必须被初始化。但是,final空白在final关键字final的使用上提供了更大的灵活性,为此,一个类中的final数据成员就可以实现依对象而有所不同,却有保持其恒定不变的特征。

package EmployeeTest_4_2;

public class Test3 { private final String s = "final变量"; private final int A = 100; public final int B = 90; public static final int C = 80; public static final int D = 70; public final int E;//final空白,必须在初始化对象的时候赋初值 public Test3(int x) { E = x; } public static void main(String[] args) { Test3 t = new Test3(2); // t.A = 101;//final变量的值一旦给定就无法改变 // t.B = 91; // t.C = 81; // t.D = 71; System.out.println(t.A); System.out.println(t.B); System.out.println(t.C); //不推荐用对象方式访问静态字段 System.out.println(t.D); System.out.println(Test3.C); System.out.println(Test3.D); //System.out.println(Test3.E);//出错,因为E为final空白,依据不同对象值有所不同. System.out.println(t.E); Test3 t1 = new Test3(3); System.out.println(t1.E);//final空白变量E依据对象的不同而不同 } private void test() { System.out.println(new Test3(1).A); System.out.println(Test3.C); System.out.println(Test3.D); } public void test2() { final int a;//final空白,在需要的时候才赋值 final int b = 4;//局部常量--final用于局部变量的情形 final int c;//final空白,一直没有给赋值. a = 3; //a=4; 出错,已经给赋过值了. //b=2; 出错,已经给赋过值了. } }

输出结果:

100 90 80 70 80 70 2 3

4. final参数

当函数参数为final类型的时候,可以读取使用该参数,但是无法修改该参数的值。

代码语言:javascript
复制
package EmployeeTest_4_2;

public class Test4 
{
	public static void main(String[] args)
	{
		new Test4().f1(1);
	}
	
	public void f1(final int i)
	{
		System.out.println(i);
	}

}

总结:

  1、final修饰类

final修饰的类不允许被继承。一个类不能既是final的,又是abstract的,因为抽象类的目的就是为了让子类去实现其中的方法,而final修饰的类不能被继承,所以产生了矛盾。

2、final修饰方法

final修饰方法,表示该方法不能被子类重写Override。

3、final修饰变量

final成员变量表示常量,只能被赋值一次,赋值后的值不能改变。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-04-22 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档