浅析java一些修饰符
2016-07-24 15:16
357 查看
一.final修饰符:
作用域:类、方法、成员变量、局部变量、入参等
final修饰类:
final修饰的类就是传说中的不可变类,比如jdk里的Integer,Double,String等常用的基本数据类型。同时这个类是不能被继承的,而它的成员变量可以根据需要设置为final,所有成员方法都默认为final,不能被重写。也就是说如果一个类你确定不想让其他类来继承的话可以选择final修饰。
final修饰方法:
final方法是不能被重写的,也就是说你确定这个方法不想被子类 覆盖的情况下才需要将其设置为final方法。
final修饰成员变量:
final修饰的成员变量,一旦被赋值以后就不能重新复制,包含两个层面:如果是基本数据类型的变量其数值在初始化之后就不能更改;如果是引用类型的变量,它在初始化之后就不能修改它的指向,就是不能再指向另外一个对象。
final修饰的成员变量需要立即初始化。也就是说final修饰的成员变量需要在定义的时候就直接赋值,或者在构造器中对它进行赋值,也可以在代码块中对其赋值,因为编译后代码块中的代码是排在构造器中代码之前执行的,但是三者只能选择其一为变量赋值。
当然如果将final字段设置为static,则它只能在定义时以及静态代码块中进行初始化。
final修饰局部变量:
因为系统不会为局部变量进行初始化,所以在定义final的局部变量时可以不对其进行初始化,与普通局部变量一样需要在使用之前进行初始化,但是final的局部变量只能赋值一次。
final变量和普通变量的区别还在于当final变量是基本数据类型或者String时,如果能在编译期间明确知道它的具体值,则编译器会对它进行优化,直接将它作为常量来替换掉final变量。比如下面的代码:
输出结果:
从结果可以看出来d=b+” world” 相当于是”hello”+” world” 的结果,也就是说编译器在编译阶段将final b直接用”hello” 替换了。当然这种优化是在编译器在编译期间明确知道变量的值的前提下来进行优化的。
5. final修饰入参:
final修饰的入参的理解也许不是那么深入,首先看一段代码:
输出为:
从代码中可以看出,final修饰的入参是不支持修改的,也就是说是不支持重新赋值的,就是代码中注释掉的部分,编译器就会直接报错的。但是final的入参是引用类型时,其对象的中的数据是可以修改的,只是不允许该引用指向其他对象。
一般final的入参可以用于在装载集合的函数中,我们把需要装载的集合定义为final,就可以保证在函数的执行过程中传入的集合引用不会被篡改。
作用域:类、方法、成员变量、局部变量、入参等
final修饰类:
final修饰的类就是传说中的不可变类,比如jdk里的Integer,Double,String等常用的基本数据类型。同时这个类是不能被继承的,而它的成员变量可以根据需要设置为final,所有成员方法都默认为final,不能被重写。也就是说如果一个类你确定不想让其他类来继承的话可以选择final修饰。
final修饰方法:
final方法是不能被重写的,也就是说你确定这个方法不想被子类 覆盖的情况下才需要将其设置为final方法。
final修饰成员变量:
final修饰的成员变量,一旦被赋值以后就不能重新复制,包含两个层面:如果是基本数据类型的变量其数值在初始化之后就不能更改;如果是引用类型的变量,它在初始化之后就不能修改它的指向,就是不能再指向另外一个对象。
final修饰的成员变量需要立即初始化。也就是说final修饰的成员变量需要在定义的时候就直接赋值,或者在构造器中对它进行赋值,也可以在代码块中对其赋值,因为编译后代码块中的代码是排在构造器中代码之前执行的,但是三者只能选择其一为变量赋值。
private final String string = "hello world";//直接初始化 public Test(String string) { this.string = string;//构造器初始化 } { string="hello world";//代码块中初始化 }
当然如果将final字段设置为static,则它只能在定义时以及静态代码块中进行初始化。
final修饰局部变量:
因为系统不会为局部变量进行初始化,所以在定义final的局部变量时可以不对其进行初始化,与普通局部变量一样需要在使用之前进行初始化,但是final的局部变量只能赋值一次。
final变量和普通变量的区别还在于当final变量是基本数据类型或者String时,如果能在编译期间明确知道它的具体值,则编译器会对它进行优化,直接将它作为常量来替换掉final变量。比如下面的代码:
@org.junit.Test public void testFinal(){ String a="hello world"; final String b="hello" ; String c = "hello"; System.out.println(b==c); String d = b+" world"; String e = c + " world"; System.out.println(a==d); System.out.println(a==e); String f = "hello" + " world"; System.out.println(a==f); }
输出结果:
true true false true
从结果可以看出来d=b+” world” 相当于是”hello”+” world” 的结果,也就是说编译器在编译阶段将final b直接用”hello” 替换了。当然这种优化是在编译器在编译期间明确知道变量的值的前提下来进行优化的。
5. final修饰入参:
final修饰的入参的理解也许不是那么深入,首先看一段代码:
@org.junit.Test public void testFinalRucan(){ int a = 10; StringBuilder string = new StringBuilder("hello"); List<String> list = new ArrayList<String>(); list.add(string.toString()); xiuGaiRuCan(a,string,list); System.out.println(a); System.out.println(string); System.out.println(list); } public void xiuGaiRuCan(final int i, final StringBuilder string, final List<String> list){ // i++; // string = new StringBuilder(); // list = new ArrayList<String>(); string.append(" world"); list.add(string.toString()); }
输出为:
0 hello world [hello, hello world]
从代码中可以看出,final修饰的入参是不支持修改的,也就是说是不支持重新赋值的,就是代码中注释掉的部分,编译器就会直接报错的。但是final的入参是引用类型时,其对象的中的数据是可以修改的,只是不允许该引用指向其他对象。
一般final的入参可以用于在装载集合的函数中,我们把需要装载的集合定义为final,就可以保证在函数的执行过程中传入的集合引用不会被篡改。
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树