Java读书笔记十三(Java中的Final关键字)

 

 前言

 在java中final关键字可用于修饰类、变量和方法,用于表示它修饰的类、方法和变量都是不可变的。下面小编在剖析一下final关键字常用的场景。

 

 Final成员变量

 在java中成员变量是随类初始化或者对象初始化而初始化的,而对于final修饰的成员变量而言,一旦有了初始值,就不能被重新赋值,如果既没有在定义成员变量时指定初始值,也没有在初始化块、构造器中为成员变量指定初始值,那么将是系统默认分配的0、false或者null。总结一下为final修饰的成员变量也就以下两种情况:

 类变量:必须在静态初始化块中指定初始值或者声明变量时指定初始值,而且只能在两个地方的其中之一指定。

 实例变量:必须在非静态初始化块、声明该实例变量或构造器中指定初始值,而且只能在三个地方的其中之一指定。

 看下面这个Demo,来了解一下各种情况。

package com.test;

public class FinalVariableTest {
	// 定义成员变量时指定默认值,合法。
	final int a = 6;
	// 下面变量将在构造器或初始化块中分配初始值
	final String str;
	final int c;
	final static double d;
	// 既没有指定默认值,又没有在初始化块、构造器中指定初始值,
	// 下面定义的ch实例变量是不合法的。
	// final char ch;
	// 初始化块,可对没有指定默认值的实例变量指定初始值
	{
		// 在初始化块中为实例变量指定初始值,合法
		str = "Hello";
		// 定义a实例变量时已经指定了默认值,
		// 不能为a重新赋值,因此下面赋值语句非法
//		 a = 9;
	}
	// 静态初始化块,可对没有指定默认值的类变量指定初始值
	static {
		// 在静态初始化块中为类变量指定初始值,合法
		d = 5.6;
	}

	// 构造器,可对既没有指定默认值、有没有在初始化块中
	// 指定初始值的实例变量指定初始值
	public FinalVariableTest() {
		// 如果在初始化块中已经对str指定了初始化值,
		// 构造器中不能对final变量重新赋值,下面赋值语句非法
//		 str = "java";
		c = 5;
	}

	public void changeFinal() {
		// 普通方法不能为final修饰的成员变量赋值
		// d = 1.2;
		// 不能在普通方法中为final成员变量指定初始值
		// ch = 'a';
	}

	public static void main(String[] args) {
		FinalVariableTest ft = new FinalVariableTest();
		System.out.println(ft.a);
		System.out.println(ft.c);
		System.out.println(ft.d);
	}
}


 final局部变量

 系统不会对局部变量进行初始化,局部变量必须由程序员进行初始化。如果final修饰的局部变量在定义时没有指定默认值,则可以在后面代码中指定,但是只能指定一次。


 final方法

 final修饰的方法不可以被重写,如果出于某些原因,不希望子类重写父类的方法,可以使用该关键字

 final类

 final修饰的类不可以有子类,因为如果有子类的话,那么子类可以访问到父类的某些方法,就可以来改写父类中的内部数据。


不可变类

 不可以变类的意思是当创建该类实例后,该实例的实例变量是不可以修改的。那么如果要自定义不可变类的话,需要遵循以下规则

 1.使用private和final修饰符类修饰该类的成员变量

 2.提供带参数的构造器,用于根据传入的参数来初始化类里的成员变量

 3.仅仅为该类的成员变量提供getter方法,不要为该类的成员变量提供setter方法,因为普通方法无法修改final修饰的成员变量

你可能感兴趣的:(Java读书笔记十三(Java中的Final关键字))