Java基础: 关键字 final
2011-06-03 21:17
579 查看
1. 修饰变量
该变量既可以是局部变量也可以是成员变量,final关键字修饰的成员变量即常量,可以被继承或者覆盖和隐藏!主要从以下两方面来说明问题。
<1> 修饰基本数据类型
final修饰的该变量就是常量,一旦赋值不可以改变其值。
一般情况,final修饰成员变量的话与static结合,使该常量可以被类直接调用,而不必创建对象,节省空间。再者,如果该常量中不含不确定因素,就称之为编译时期常量,反之为运行期常量。编译时期常量被调用时不会加载该类。http://blog.csdn.net/AndroidBluetooth/archive/2011/05/30/6454135.aspx
注意:测试方法(main方法)写在该类中会加载该类的,所以测试方法放在单独一个类中。例子:
结果:
还有这样一种情况,不想在声明常量的时候,给其赋值,那么怎么办?
我们知道,如果在声明常量的同时不将其赋值,编译器会给我们一个类似The blank final field NAME may not have been initialized的错误。
第一种办法,在静态代码块中给常量赋值。
结果:
分析:由于NAME是含有不确定因素,所以会加载静态代码块,从而将其初始化。
注意:动态代码块无法完成final变量的初始化
第二种方法,在构造方法中初始化
如果这样做,那么成员常量不可以被static修饰。
static无法修饰构造方法,因为构造方法是在创建对象时被调用的,而static修饰的,只会在加载该类时被加载一次。
结果:
那么,有人说了,现在只有一个构造方法,如果再加一个或者n个构造方法呢,难道还要初始化吗???yes,恭喜你,答对了。必须的,否则你得到类似这样一个错误:
例子:
所以,正常情况下,不会使用这种方式。
<2> 修饰引用类型数据
注意:数组也是引用类型。
final修饰的引用不变指的是它的栈内存地址不变,即永远指向那个堆里的对象,但是堆里的对象(属性)是可变的!
示例:
测试方法:
但是我们可以修改其属性值。
结果:
2. 修饰类
final关键字修饰的类,类中成员方法默认为final,无法被继承!Java提供的包中,String类就是一个用关键字final修饰的类,所以其他类无法继承他!但是final关键字修饰的类可以作为子类,即可以继承其他类!
3. 修饰方法
final关键字修饰的方法,可以被继承,但是不能被覆盖!这样可以保证代码的安全性。
注意:final和static一样不可以修饰构造方法。
4. final与abstract
final修饰的类不可以被继承,然而abstract修饰的类本意就是希望子类去继承。所以,在Java中不允许final修饰abstract,无论是abstract方法还是abstract类。
如果你这样子去修饰一个抽象类的话:
编译器毫不客气的给你一个错误信息:
同样的道理,final也不可以修饰abstract方法,如:
错误:
从这句话中我们也可以得出结论:抽象方法不可以是private的,可以是default或者public或者protected。因为private方法子类不可见,更无法继承或者重写。
5. final与接口
final不能修饰interface接口
6. final与构造方法
final不可以修饰构造方法
该变量既可以是局部变量也可以是成员变量,final关键字修饰的成员变量即常量,可以被继承或者覆盖和隐藏!主要从以下两方面来说明问题。
<1> 修饰基本数据类型
final修饰的该变量就是常量,一旦赋值不可以改变其值。
一般情况,final修饰成员变量的话与static结合,使该常量可以被类直接调用,而不必创建对象,节省空间。再者,如果该常量中不含不确定因素,就称之为编译时期常量,反之为运行期常量。编译时期常量被调用时不会加载该类。http://blog.csdn.net/AndroidBluetooth/archive/2011/05/30/6454135.aspx
注意:测试方法(main方法)写在该类中会加载该类的,所以测试方法放在单独一个类中。例子:
package mark.zhang; public class Linux { // 修饰成员变量 public static final String NAME = "LINUX"; static { System.out.println("--Linux---静态代码块"); } { System.out.println("--Linux---动态代码块"); } public Linux() { } public void getName() { // 修饰局部变量 final int i = 7; } } class Test { public static void main(String[] args) { System.out.println(Linux.NAME); } }
结果:
LINUX
还有这样一种情况,不想在声明常量的时候,给其赋值,那么怎么办?
我们知道,如果在声明常量的同时不将其赋值,编译器会给我们一个类似The blank final field NAME may not have been initialized的错误。
第一种办法,在静态代码块中给常量赋值。
package mark.zhang; public class Linux { // 修饰成员变量 public static final String NAME; static { System.out.println("--Linux---静态代码块"); NAME = "LINUX"; } { System.out.println("--Linux---动态代码块"); } public Linux() { } } class Test { public static void main(String[] args) { System.out.println(Linux.NAME); } }
结果:
--Linux---静态代码块 LINUX
分析:由于NAME是含有不确定因素,所以会加载静态代码块,从而将其初始化。
注意:动态代码块无法完成final变量的初始化
第二种方法,在构造方法中初始化
如果这样做,那么成员常量不可以被static修饰。
static无法修饰构造方法,因为构造方法是在创建对象时被调用的,而static修饰的,只会在加载该类时被加载一次。
package mark.zhang; public class Linux { // 修饰成员变量,这里没有static public final String NAME; static { System.out.println("--Linux---静态代码块"); } { System.out.println("--Linux---动态代码块"); } public Linux() { NAME = "LINUX"; } } class Test { public static void main(String[] args) { System.out.println(new Linux().NAME); } }
结果:
--Linux---静态代码块 --Linux---动态代码块 LINUX
那么,有人说了,现在只有一个构造方法,如果再加一个或者n个构造方法呢,难道还要初始化吗???yes,恭喜你,答对了。必须的,否则你得到类似这样一个错误:
The blank final field NAME may not have been initialized
例子:
public Linux() { NAME = "LINUX"; } public Linux(String name) { NAME = "LINUX--LINUX"; }
所以,正常情况下,不会使用这种方式。
<2> 修饰引用类型数据
注意:数组也是引用类型。
final修饰的引用不变指的是它的栈内存地址不变,即永远指向那个堆里的对象,但是堆里的对象(属性)是可变的!
示例:
package mark.zhang; public class Linux { private String name = "linux OS"; static { System.out.println("--Linux---静态代码块"); } { System.out.println("--Linux---动态代码块"); } public Linux() { } public void setName(String name) { this.name = name; } public String getName() { return name; } }
测试方法:
class Test { public static void main(String[] args) { final Linux linux = new Linux(); System.out.println("linux's name : " + linux.getName()); // error: The final local variable linux cannot be assigned. It must be // blank and not using a compound assignment // linux = new Linux(); } }
但是我们可以修改其属性值。
class Test { public static void main(String[] args) { final Linux linux = new Linux(); System.out.println("before--" + "linux's name : " + linux.getName()); linux.setName("ubuntu10.10"); System.out.println("after--" + "linux's name : " + linux.getName()); } }
结果:
--Linux---静态代码块 --Linux---动态代码块 before--linux's name : linux OS after--linux's name : ubuntu10.10
2. 修饰类
final关键字修饰的类,类中成员方法默认为final,无法被继承!Java提供的包中,String类就是一个用关键字final修饰的类,所以其他类无法继承他!但是final关键字修饰的类可以作为子类,即可以继承其他类!
3. 修饰方法
final关键字修饰的方法,可以被继承,但是不能被覆盖!这样可以保证代码的安全性。
注意:final和static一样不可以修饰构造方法。
package mark.zhang; public class Linux { static { System.out.println("--Linux---静态代码块"); } { System.out.println("--Linux---动态代码块"); } public Linux() { } /** * final修饰的方法可以被子类继承,但是不可以被子类重写 子类中也不可以与同名的该方法 */ public final void getInfo() { System.out.println("linux2.38"); } } class Ubuntu extends Linux { // 一下两种方式均会包类似下面的错误 // Cannot override the final method from Linux /* * public final void getInfo() { System.out.println("ubuntu10.10"); } */ /* * public void getInfo() { System.out.println("ubuntu10.10"); } */ } class Test { public static void main(String[] args) { Ubuntu ubuntu = new Ubuntu(); // 可以继承父类的final方法 ubuntu.getInfo(); } }
4. final与abstract
final修饰的类不可以被继承,然而abstract修饰的类本意就是希望子类去继承。所以,在Java中不允许final修饰abstract,无论是abstract方法还是abstract类。
如果你这样子去修饰一个抽象类的话:
final abstract class Ubuntu { abstract void get(); }
编译器毫不客气的给你一个错误信息:
The class Ubuntu can be either abstract or final, not both
同样的道理,final也不可以修饰abstract方法,如:
abstract class Ubuntu { final public abstract void get(); }
错误:
The abstract method get in type Ubuntu can only set a visibility modifier, one of public or protected
从这句话中我们也可以得出结论:抽象方法不可以是private的,可以是default或者public或者protected。因为private方法子类不可见,更无法继承或者重写。
5. final与接口
final不能修饰interface接口
6. final与构造方法
final不可以修饰构造方法
相关文章推荐
- java基础之final关键字作用
- java基础案例:final关键字
- 第2章 Java编程基础——FAQ2.07 final关键字有什么含义?具体如何应用?
- 黑马程序员——Java基础:继承、final关键字、抽象、接口、多态
- java夯实基础系列:深入理解static、final关键字
- java基础之short案例分析以及final关键字
- java基础关键字之Static和final
- Java基础之Final关键字
- java基础:final关键字的深入使用
- java基础---(1)java中的final,static关键字
- [Java基础] final关键字
- 【Java基础】java中常用关键字理解this、static、final、volatile理解
- java基础学习面向对象之final关键字 五-9
- java基础语法之final关键字
- java基础----->Static 和 Final 关键字
- Java 基础之(六) final关键字
- java基础之short案例分析以及final关键字
- 【Java基础】final关键字总结
- Java基础知识——final关键字
- JAVA基础学习之final关键字、遍历集合、日期类对象的使用、Math类对象的使用、Runtime类对象的使用、时间对象Date(两个日期相减)(5)