java的final关键字的使用


文章内容选自尚硅谷,jdk8,eclipse环境

final关键字的使用

final关键字可以修饰类、方法、变量

final关键字修饰类

final关键字修饰的类不能够被继承,比如说java标准库中的String类、System类、StringBuffer类

package com.atguigu.java3;

public class FinalTest {
    
    

}

//class A extends String{
    
    
//	
//}

注释的部分编译器会报错,这是因为标准库中的String类有关键字final修饰,表示String类不能够被继承

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    
    
    /** The value is used for character storage. */
    private final char value[];

    /** Cache the hash code for the string */
    private int hash; // Default to 0

    /** use serialVersionUID from JDK 1.0.2 for interoperability */
    private static final long serialVersionUID = -6849794470754667710L;

以上是标准库中的String定义,有关键字final修饰。

final修饰方法

final关键字修饰的方法表示改方法不能够被重写,比如说Object类中的getClass方法

//class AA{
    
    
//	public void getClass(){
    
    
//		
//	}
//}

注释到的部分编译器也会报错,因为getClass方法返回当前对象所属类,在Object类中,该方法被final修饰,无法重写。
ps:按住crtl+shift+t找到Object类,再按住ctrl+o会显示该类的所有方法,点击getClass。

    public final native Class<?> getClass();

    /**
     * Returns a hash code value for the object. This method is
     * supported for the benefit of hash tables such as those provided by

可见,类中的getClass方法也有final修饰
ps:我们发现这儿的方法没有显示方法体,而且还有一个native关键字,native关键字的意思是该方法的方法体是由c或c++写的,不是用java代码写的,属于底层代码,故不显示。

final修饰变量

  • final修饰的变量,此时的变量变为一个常量了,常量就意味着它不允许被修改。
  • final修饰的变量,一般写作大写形式。

final修饰变量,则final也能修饰属性,因为属性也属于变量。final修饰属性的时候,可以显式赋值,也可以在代码块中初始化、构造器初始化。

final修饰属性时显式初始化

final修饰属性的时候不能够默认初始化

package com.atguigu.java3;

public class FinalTest {
    
    
	final int WIDTH = 0;
}

如果没有final关键字,尽管如果不给属性WIDTH赋初值,采用默认初始化也为0,但是这儿有final关键字修饰,必须采用显式初始化。
ps:ctrl+shift+x能够把小写字母改为大写字母。

final修饰属性时代码块中初始化

package com.atguigu.java3;

public class FinalTest {
    
    
	final int WIDTH = 0;
	final int LEFT;
	
	{
    
    
		LEFT = 1;
	}
}

final修饰属性时构造器中初始化

采用构造器初始化能够给对象的final属性赋自己需要的值,相较于显式赋值更加灵活。

package com.atguigu.java3;

public class FinalTest {
    
    
	final int WIDTH = 0;
	final int LEFT;
	final int RIGHT;
	
	{
    
    
		LEFT = 1;
	}
	
	public FinalTest(){
    
    
		RIGHT =2;
	}
	
//	public FinalTest(){
    
    
//		
//	}
}

注释掉的部分报错,通过构造器初始化的时候,注意必须在每个构造器内部都给final属性赋值,因为我们调用构造器的时候只能调用一个,因为得保证每个构造器都给final修饰的属性赋值。

如果在注释掉的构造器内部加上RIGHT的赋值语句,编译就通过了。

public class FinalTest {
    
    
	final int WIDTH = 0;
	final int LEFT;
	final int RIGHT;
	
	{
    
    
		LEFT = 1;
	}
	
	public FinalTest(){
    
    
		RIGHT =2;
	}
	
	public FinalTest(int n){
    
    
		RIGHT = n;
	}
}

此时可以通过构造器给属性RIGHT赋任意int型的值了。

ps:final修饰的属性不能够通过 对象.属性 来赋值,因为我们通过 对象.属性 来赋值,前提是现有了对象,而我们在创建对象的时候,所定义的属性必须有个初始值,这个初始值可以是默认初始值,也可以是构造器初始化的值,反正必须有一个值。可是我们在定义类的时候,把属性用final修饰了,属性就为一个常量了,又因为final修饰的属性不能用默认初始化。所以必须通过其他方式初始化后,才能创建对象。故 对象.属性 不能修改值,因为final属性是一个常量,不允许被修改。

final修饰局部变量

public class FinalTest {
    
    
	final int WIDTH = 0;
	final int LEFT;
	final int RIGHT;
	
	{
    
    
		LEFT = 1;
	}
	
	public FinalTest(){
    
    
		RIGHT =2;
	}
	
	public FinalTest(int n){
    
    
		RIGHT = n;
	}
	
	public void show(final int num){
    
    
//		num = 20;//常量不允许被修改,只能被调用
		System.out.println(num);
	}
	
	public static void main(String[] args) {
    
    
		FinalTest test = new FinalTest();
		test.show(10);
	}
	
}

输出结果为10
此处show方法之所以编译通过,是因为形参就只有被调用的时候才在栈空间中声明变量,并且传递一个实参值,有点类似于属性的显式初始化了。因此编译通过,由于已经用final修饰形参,故show方法内的num只能被调用,不能被修改。num = 20; 编译器会报错。

补充:static final修饰属性,意为全局常量,static关键字修饰的属性意味着通过类的加载而加载,就这一份,通过类直接调,体现全局,final体现常量。

猜你喜欢

转载自blog.csdn.net/Meloneating/article/details/114164412