1.final 修饰类时表明该类不能被继承,自然类中的方法默认是final型的。
2.final 修饰方法时不允许被子类覆盖,也就是可以被继承。一个final类中,一个final方法只能被实现一次。
public class Test1 { public final void show(){ System.out.println("this is super class"); } }
上面作为下面类的父类使用。
public class Test extends Test1 { // public void show(){ //这里如果企图重写覆盖父类中final修饰的方法会报错。 // // } public static void main(String[] args){ Test t=new Test(); t.show(); } }
3.final 修饰的成员变量只能被赋值一次。如果是引用类型的变量,则不能让该变量再去指向其他对象。
Object a=new Object(); final Object b=a; //b为a的引用变量,当改变b的指向时,如下一行会报错 b=new Object(); //报错
如果所指的变量重新赋值会出现什么情况呢,如下面中的a变化时,b会如何呢?
public static void main(String[] args){ int a=1; final int b=a; System.out.println(a); System.out.println(b); a=2; System.out.println(a); System.out.println(b); //这里的b其实还是指代最初的1,总之记住一句话,一旦b被初始化,则不能改变。
Final类中的成员变量只要没有添加final修饰都可以照常操作。如
public final class Test { int a=3; public static void main(String[] args){ Test b=new Test(); b.a=4; //如果a添加final修饰则会报错 System.out.println(b.a); //这里输出值为4. } }
final在修饰类中成员变量时可以不给初值,但是必须保证在使用前初始化。尽管如此,这也提供了很大的灵活性。尽管初始化之后不能再改变,但通过构造函数,我们可以让final变量依据使用对象而改变。如下:
public class Test1 { public final int a; //这里声明的final型变量可以不赋值,但是必须给出一个类似的构造函数,不能使用普通方法赋值。如果子类继承该类则必须在构造方法中给出一个<span style="font-family: Arial, Helvetica, sans-serif;"> //确定的值。这都是因为final类型变量必须在使用之前初始化。</span> public Test1(int a){ this.a=a; } }
4,final 参数。
传递的实参数如果是final 型,而形参不要求则很容易理解。形参的改变与实参无关。如果需要传递的形参是final型,则试图改变形参值。会出错。
public class Test1 { public void show(final int i){ i++;//这里会报错,提示形参不能重新赋值。 } public static void main(String[] args){ (new Test1()).show(3); } }对于博文http://www.cnblogs.com/dolphin0520/p/3736238.html中认为“ ” 当你在方法中不需要改变作为参数的对象变量时,明确使用final进行声明,会防止你无意的修改而影响到调用方法外的变量”不当,并举了几个例子。我去搜查了一下,发现JDK中有这样一句话: Once a final variable has been assigned, it always contains the same value. If a final variable holds a reference to an object, then the state of the object may be changed by operations on the object, but the variable will always refer to the same object.----取自博文http://blog.csdn.net/zhengqiqiqinqin/article/details/14497479。这句话翻译过来应该是如果final修饰的变量一旦被赋值,则不允许改变。如果final修饰的变量是对某对象的引用,则该变量会一直指向对象,但是该对象的状态可以改变。换句话说如果final修饰的是int ,double,byte,char等基本数据类型,一旦赋值不可改变。如果修饰的是某类对象如StringBuffer,Date型则变量会一直指向该变量,但该对象中的内容可以改变,如下:
public class Test1 { public void show (final Test test){ test.i++; //这里不会报错 System.out.println(test.i); } public static void main(String[] args){ Test t=new Test(); //这里Test是另外一个类,类中我给的i值为一,传过去之后可以看到输出的值为2; (new Test1()).show(t); } }
遇到final时请记住一句话一旦被赋值则不可另外再改变。如果final修饰变量指向对象,则对象中的成员变量可以改变,只不过final在这里的作用就好像把变量当成了一个标签贴在了特定的盒子上,至于盒子里的内容不管,可是如果你想把标签撕下贴到其他同类型的盒子上,那就要出错了。
static
static主要作用就是在不创建对象的情况下,通过类名来访问类中的静态方法和静态成员变量。
1.static修饰方法。
static修饰的方法中不得含有非静态的方法和非静态的变量。因为非静态的方法和变量通常是和对象绑定在一块的。而static方法是和对象无关。
static修饰的变量,不会影响到对象访问权限(方法也是),静态变量和类绑定只存在一个副本,而那些和对象绑定的变量则因为对象不同,可以存在多个副本也不会冲突。
static修饰模块。通常static修饰模块主要作用就是优化程序性能,就是速度快一些之类的意思。
总之,static 就是告诉计算机某个变量或方法或代码块你只给我留一份就行,任何该类的对象都得共享这一块。由于凡是static 修饰的都只加载一次,尤其当对象较多频繁使用某一块代码时,添加static修饰,程序性能会优很多。
关于static的详细解释参看http://www.cnblogs.com/dolphin0520/p/3799052.html。
对于static、final共同修饰的变量方法有两层含义,可以通过类直接访问;不能改变其值或覆盖。在访问上,可以通过非静态方法,对象访问静态变量方法,但是不建议还是用类好一些。
本文主要参考的文章除了以上提到的外还有http://lavasoft.blog.51cto.com/62575/18771/,这里也是讲的static和final区别。本文系自己读了很多牛人写的之后感想制作。仅作交流,如果不当,敬请留言讨论。一块学习,共同提高。