-
Java的final关键字
2019-03-26 15:29:52Java的final关键字 >引言 > >Java中的final 与C++中的const 差不多,其代表修饰的变量不可改变。不过final 可以修饰类 final修饰有下面几种: 修饰局部变量 修饰非局部变量 修饰函数 修饰类 1.修饰局部...Java的final关键字
>引言 > >Java中的final 与C++中的const 差不多,其代表修饰的变量不可改变。不过final 可以修饰类
final修饰有下面几种:
- 修饰局部变量
- 修饰非局部变量
- 修饰函数
- 修饰类
1.修饰局部变量
final修饰的局部变量是常量,只能赋值一次。
public class Kit { public static void main(String[] arg) { final int a; a=10;//不能再修改了 //a=100;//这里报错,初始化后的值不能被修改 final int b=100;//不能再修改了 } }
2.修饰非局部变量
用final定义成员变量的必须对它进行初始化(也可以在构造函数中初始化),之后该变量的值不能被改变。
这是一个错误的示范:
package test; class A { int a; public final int PI; A(){};//errors:The blank final field PI may not have been initialized public String toString() { return "This class A of toString function"; } }
3.修饰方法
用final修饰的方法不能被子类重写。
>这里与c++稍有不同,c++中用const修饰成员函数不能修改该对象成员的值。
4.修饰类
用final修饰的类被称为最终类,该类不能被继承。比如String类
-
java的final关键字_Java中的Final关键字解析
2021-03-06 01:37:18这篇文章主要讲解Java中final关键字的使用,对于final大家从字面意思就能看出来,主要是“最终的不可改变的意思”。可以修饰类、方法和变量。先给出这篇文章的大致脉络。首先,先给出final关键字的三种使用场景,也...这篇文章主要讲解Java中final关键字的使用,对于final大家从字面意思就能看出来,主要是“最终的不可改变的意思”。可以修饰类、方法和变量。先给出这篇文章的大致脉络。
首先,先给出final关键字的三种使用场景,也就是修饰类,方法和变量
然后,深入分析final关键字主要注意的几个问题
最后,总结一下final关键字
OK,开始今天的文章
一、final关键字的基本使用
1、认识final关键字
final可以修饰类、方法、变量。那么分别是什么作用呢?
(1)修饰类:表示类不可被继承
(2)修饰方法:表示方法不可被覆盖
(3)修饰变量:表示变量一旦被赋值就不可以更改它的值。java中规定final修饰成员变量必须由程序员显示指定变量的值。
2、final关键字修饰类
final关键字修饰类表示这个类是不可被继承的,如何去验证呢?
3、final关键字修饰方法
final修饰的方法不能被重写。但是可以重载。下面给出了一个代码例子。主要注意的是:父类中private的方法,在子类中不能访问该方法,但是子类与父类private方法相同的方法名、形参列表和返回值的方法,不属于方法重写,只是定义了一个新的方法。
public class FinalClass{
public final void test(){}
public final void test(int i){}
}
4、final关键字修饰变量
final关键字修饰变量,是比较麻烦的。但是我们只需要对其进行一个分类介绍就能理解清楚了。
(1)修饰成员变量
如果final修饰的是类变量,只能在静态初始化块中指定初始值或者声明该类变量时指定初始值。
如果final修饰的是成员变量,可以在非静态初始化块、声明该变量或者构造器中执行初始值。
(2)修饰局部变量
系统不会为局部变量进行初始化,局部变量必须由程序员显示初始化。因此使用final修饰局部变量时,即可以在定义时指定默认值(后面的代码不能对变量再赋值),也可以不指定默认值,而在后面的代码中对final变量赋初值(仅一次)。
下面使用代码去验证一下这两种情况
public class FinalVar {
finalstatic int a = 0;//再声明的时候就需要赋值
public static void main(String[] args) {
finalint localA; //局部变量只声明没有初始化,不会报错,与final无关。
localA = 0;//在使用之前一定要赋值
//localA = 1; 但是不允许第二次赋值
}
}
(3)修饰基本类型数据和引用类型数据
如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;
如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象。但是引用的值是可变的。
修饰基本类型的数据,在上面的代码中基本上能够看出,下面主要是描述引用类型的变量
public class FinalReferenceTest{
public static void main(){
finalint[] iArr={1,2,3,4};
iArr[2]=-3;//合法
iArr=null;//非法,对iArr不能重新赋值
final Person p = new Person(25);
p.setAge(24);//合法
p=null;//非法
}
}
二、final关键字需要注意的几个问题
1、final和static的区别
其实如果你看过我上一篇文章,基本上都能够很容易得区分开来。static作用于成员变量用来表示只保存一份副本,而final的作用是用来保证变量不可变。下面代码验证一下
public class FinalTest {
public static void main(String[] args) {
AA aa1 = new AA();
AA aa2 = new AA();
System.out.println(aa1.i);
System.out.println(aa1.j);
System.out.println(aa2.i);
System.out.println(aa2.j);
}
}
//j值两个都一样,因为是static修饰的,全局只保留一份
//i值不一样,两个对象可能产生两个不同的值,
class AA {
public final int i = (int) (Math.random()*100);
public static int j = (int) (Math.random()*100);
}
//结果是 65、23、67、23
2、为什么局部内部类和匿名内部类只能访问局部final变量?
为了解决这个问题,我们先要去使用代码去验证一下。
public class Test {
public static void main(String[] args) {
}
//局部final变量a,b
public void test(final int b) {
finalint a = 10;
//匿名内部类
new Thread(){
public void run() {
System.out.println(a);
System.out.println(b);
};
}.start();
}
}
上段代码中,如果把变量a和b前面的任一个final去掉,这段代码都编译不过。
这段代码会被编译成两个class文件:Test.class和Test1.class。默认情况下,编译器会为匿名内部类和局部内部类起名为Outter1.class。
原因是为什么呢?这是因为test()方法里面的参数a和b,在运行时,main线程快要结束,但是thread还没有开始。因此需要有一种机制,在使得运行thread线程时候能够调用a和b的值,怎办呢?java采用了一种复制的机制,
也就说如果局部变量的值在编译期间就可以确定,则直接在匿名内部里面创建一个拷贝。如果局部变量的值无法在编译期间确定,则通过构造器传参的方式来对拷贝进行初始化赋值。
三、总结
final关键字主要用在三个地方:变量、方法、类。
对于一个final变量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象。
当用final修饰一个类时,表明这个类不能被继承。final类中的所有成员方法都会被隐式地指定为final方法。
使用final方法的原因有两个。第一个原因是把方法锁定,以防任何继承类修改它的含义;第二个原因是效率。在早期的Java实现版本中,会将final方法转为内嵌调用。但是如果方法过于庞大,可能看不到内嵌调用带来的任何性能提升(现在的Java版本已经不需要使用final方法进行这些优化了)。类中所有的private方法都隐式地指定为final。
好了,final关键字就写到这里,喜欢的还请大家给个关,谢谢支持,如有不对的地方还请批评。
-
java的final关键字
2020-10-11 18:37:49final在程序之中描述的是种终结器的概念,在java里面使用final关键字可以实现如下功能:定义不能被继承的类,不能够被覆写的方法,常量。 1、使用final定义不能被继承的类 final class Person{ //这个类不能够有...final在程序之中描述的是种终结器的概念,在java里面使用final关键字可以实现如下功能:定义不能被继承的类,不能够被覆写的方法,常量。
1、使用final定义不能被继承的类
final class Person{ //这个类不能够有子类 } class Student extends Person{ //错误的,继承不了 } public class JavaDemo4{ public static void main(String arge[]) { } }
2、定义不能被覆写的方法
class Person{ public final void connect() {} ; } class Student extends Person{ public void connect() {} //错误的 }
3、定义不能被覆写的常量
在有一些系统开发之中,可能使用1表示开关打开,使用0表示开关关闭,但是如果要直接操作0或者1,则会造成混乱,所以希望可以通过一些名称来表示0或者是1。而final可以定义常量,常量的内容一旦定义便不能修改。```java package mypro1 ; class Channel{ private final int ON = 1 ;//ON就是常量 private final int OFF = 0 ; //OFF就是常量 public final void connect() { ON = 2 ; } } public class JavaDemo4{ public static void main(String arge[]) { } }
实际上常量往往都是公共的定义,所以为了可以体现共享的概念,往往会使用一种全局常量的形式来定义,使用public(公共) static(共享) final(常量) 来定义全局常量。
public static final int ON =1 ;
定义全局常量时必须大写来区分(ON)public class JavaDemo4{ public static void main(String arge[]) { final String info = "mldn" ;//此时info为常量 String strA = "www.mldn.cn" ; String strB = "www."+info+".cn" ; System.out.println(strA == strB) ;//info使用final定义输出为true,相反为false } }
`在方法的时候也可以使用final来定义参数,此时也表示一个常量的概念。``
-
java的final关键字的使用
2021-02-27 10:37:41java之final关键字的使用final关键字的使用final关键字修饰类final修饰方法final修饰变量final修饰属性时显式初始化final修饰属性时代码块中初始化final修饰属性时构造器中初始化final修饰局部变量 文章内容选自...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体现常量。
-
深入理解Java的final关键字
2021-03-25 11:41:58深入理解Java的final关键字 老鼠只爱大米 2018-06-05 13:36:30 7260 收藏 65 分类专栏: Java修行之路 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接:... -
方法 类似java final_聊聊Java的final关键字
2021-02-25 19:36:35Java的final关键字在日常工作中经常会用到,比如定义常量的时候。如果是C++程序员出身的话,可能会类比C++语言中的define或者const关键字,但其实它们在语义上差距还是挺大的。在Java中,final可以用来修饰类、... -
聊聊Java的final关键字
2016-08-09 17:56:00Java的final关键字在日常工作中经常会用到,比如定义常量的时候。如果是C++程序员出身的话,可能会类比C++语言中的define或者const关键字,但其实它们在语义上差距还是挺大的。 在Java中,final可以用来修饰... -
Java的final关键字浅析
2013-08-22 18:02:00Java的final关键字表示“不可改变的”,不想改变的原因可能有两个理由:设计和效率。然而根据上下文环境,其含义有着细微的差别。final关键字可以修饰数据、方法和类。 1. final数据 在定义一个变量时,final...