final修饰符
来源:互联网 发布:ff14人女捏脸数据 编辑:程序博客网 时间:2024/06/05 07:27
final 变量
final修饰变量时,表示该变量一旦获得了初始值之后就不可被改变,final既可修饰成员变量(包括类变量和实例变量),也
可以修饰局部变量、形参。严格的说final修饰的变量不可被改变,一旦获得初始值之后,该final变量的值就不能被重新赋值。
因为final变量获得初始值之后不能被重新赋值,因此final修饰成员变量和修饰局部变量时有一定的不同。
final修饰成员变量
当使用final修饰成员变量的时候,要么在定义成员变量时候指定初始值,要么在初始化块、构造器中为成员变量赋初始值
。如果在定义该成员变量时指定了默认值,则不能在初始化块、构造器中为该属性重新赋值。归纳起来,final修饰的类属性
、实例属性能指定初始值的地方如下:
== 类属性:可在静态初始化块中、声明该属性时指定初始值。
== 实例属性:可在非静态初始化块、声明该属性、构造器中指定初始值
与普通成员变量不同的是,final成员变量(包括实例属性和类属性)必须由程序员显示初始化,系统不会对final成员进行
隐式初始化。所以,如果打算在构造器、初始化块中对final成员变量进行初始化,则不要在初始化之前就访问成员变量的值。
例如下面的成员将会引发错误。
- public class Test{
- final int age;
- {
- //系统不会对final成员变量属性进行默认初始化,所以此处代码将引起错误
- System.out.println(age);
- age = 6;
- System.out.println(age);
- }
- public static void main(String[] args){
- new Test();
- }
- }
final 修饰局部变量
系统不会对局部变量进行隐式初始化,局部变量必须由程序员显示初始化。因此使用final修饰局部变量时既可以在定义时
默认值,也可以不指定默认值。
如果final修饰的局部变量在定义时没有指定默认值,则可以在后面代码中进行对final变量赋初始值,但只能一次,不能
重复能复制;如果final修饰的局部变量在定义时已经指定默认值,则后面代码中不能再对该变量赋值。下面的程序示范了
final修饰的局部变量、形参的情形:
- public class TestFinalLocalVariable {
- public void test(final int a){
- //不能对final修饰的形参赋值,下面语句非法
- // a = 5;
- }
- public static void main(String[] args) {
- //定义final局部变量时指定默认值,则src变量无法重新赋值
- final String str = "hello";
- //下面语句非法
- // str = "java";
- //定义final局部变量时没有指定默认值,则d变量可被赋值一次
- final double d;
- //第一次赋初始值,成功
- d = 3.4;
- //对final变量重复赋值,下面语句非法
- // d = 4.6;
- }
- }
final 修饰基本类型和引用类型变量的区别
当使用final修饰基本类型变量时,不能对基本类型重新赋值,因此基本类型变量不能被改变。但对于引用类型的变量而言,
它保存的仅仅是一个引用,final只保证这个引用所引用的地址不会改变,即一直引用同一个对象,但这个对象完全可以发生
改变。
下面程序示范了final修饰数组和Tom对象的情形
- public class Tom {
- private int age;
- public Tom() {
- }
- public Tom(int age) {
- this.age = age;
- }
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
- }
- public class TestFinalReference {
- public static void main(String[] args) {
- //final修饰数组变量,iArr时一个引用变量
- final int[]iArr = {5,6,12,9};
- System.out.println(Arrays.toString(iArr));
- //对数组元素进行排序,合法
- Arrays.sort(iArr);
- System.out.println(Arrays.toString(iArr));
- //对数组元素赋值,合法
- iArr[2] = -8;
- System.out.println(Arrays.toString(iArr));
- //下面语句对iArr重新赋值,非法
- // iArr = null;
- //final修饰Tom变量,t是一个引用变量
- final Tom t = new Tom(4);
- //修改Tom对象的age属性,合法
- t.setAge(6);
- System.out.println(t.getAge());
- //下面语句对t重新赋值,非法
- // t = null;
- }
- }
从上面程序中可以看出,使用final修饰的引用类型变量不能被重新赋值,但可以改变引用型变量所引用对象的内容
final方法
final修饰方法不可被重写,出于某一些原因,不希望子类重写父类的某个方法, 则可以使用final修饰该方法。
final 类
final修饰的类不可有子类,不可被继承。
不可改变类
不可变类的意思是创建该类的实例后,该实例的属性是不可改变的。Java提供的8个包装类和lava.lang.String类都是不可改变
类,当创建他们的实例后,其实例的属性不可改变。例如下面的代码:
- Double d = new Double(6.5);
- String str = new String("hello");
上面的程序创建了一个Double对象和一个String对象,并未这两个对象传入了6.5和“hello”字符串作为参数,那么Double类
和String类肯定需要实例属性来保存这两个参数,但程序无法修改这两个实例属性,因此Double类和String类没有提供修改
他们的方法。
如果需要创建自定义的不可改变类,可遵循如下规则:
== 使用private 和final修饰符来修饰该类的属性。
== 提供带参数构造器,用于根据传入参数来初始化类里的属性
== 仅为该类的属性提供getter方法,不要为该类的属性提供setter方法,因为普通方法无法修改final修饰的属性。
== 如有必要,重写Object类中hashCode和equals方法,在equals方法根据关键属性来作为两个对象相等的标准,除此之外,还
应该保证两个用equals方法判断为相等的对象的hashCode也相等。
例如java.lang.String这个类就做的很好,他是根据String对象里的字符序列来作为相等的标准,其hashCode方法也是根据字符
序列计算得到的。下面程序测试了String类的equals和hashCode方法
- public class TestString {
- public static void main(String[] args) {
- String str1 = new String("hello");
- String str2 = new String("hello");
- //输出false
- System.out.println(str1 == str2);
- //输出true
- System.out.println(str1.equals(str2));
- //输出的hashCode
- System.out.println(str1.hashCode());
- System.out.println(str2.hashCode());
- }
- }
0 0
- final修饰符---final变量
- final修饰符---final方法
- final修饰符---final类
- final修饰符
- final修饰符解析
- final 修饰符
- final修饰符
- final修饰符
- final 修饰符
- Java Final修饰符
- final修饰符
- final修饰符
- final 修饰符
- Java final 修饰符
- Java final修饰符
- final修饰符
- final修饰符
- java修饰符:final
- 黑马程序员—Java基础—网络编程
- 初始化块
- Android Magnet:桌面删除APP自动弹出垃圾桶接受图标删除动作
- ubuntu 安装配置samba服务器
- 装饰者模式
- final修饰符
- Java中的多态(polymorphism)和动态绑定(dynamic binding)
- Alpha、Beta、RC、GA版本的区别
- 程序员技术练级攻略
- 阿里云Centos配置iptables防火墙
- 抽象类和接口
- 观察者模式
- Java集合概述
- 安装TestNG在eclipse中的插件