Java中关键字 static 与final 易错点

来源:互联网 发布:室内设计学习软件 编辑:程序博客网 时间:2024/05/23 02:23

关于Java的学习,个人算是接触一段时间了,基础的东西最近有所模糊,此文用于个人记忆使用。


1. static 关键字


作用:(static表示‘全局’或者‘静态’的意思

 被static修饰的成员变量和成员方法独立于该类的任何对象。也就是说,它不依赖类特定的实例,被类的所有实例共享。只要这个类被加载,Java虚拟机就能根据类名在运行时数据区的方法区内定找到他们。因此,static对象可以在它的任何对象创建之前访问,无需引用任何对象。
 用public修饰的static成员变量和成员方法本质是全局变量和全局方法,当声明它类的对象时,不生成static变量的副本,而是类的所有实例共享同一个static变量。
 static变量前可以有private修饰,表示这个变量可以在类的静态代码块中,或者类的其他静态成员方法中使用(当然也可以在非静态成员方法中使用--废话),但是不能在其他类中通过类名来直接引用,这一点很重要。实际上你需要搞明白,private是访问权限限定,static表示不要实例化就可以使用

1)修饰成员变量[静态变量]

使用static修饰的是静态变量,未使用static修饰的是非静态变量。

它们的区别,

静态变量在内存中只用一个拷贝,JVM只为静态分配一次内存,在加载类的过程中完成静态变量的内存分配,可以用类名直接访问(推荐),也可以使用对象进行访问。

非静态变量又称实例变量,每创建一次实例,就会为实例分配一次内存,实例变量可以在内存中有多个拷贝,互不影响。

2)修饰成员方法[静态方法]

静态方法可以使用类名直接调用,任何的实例也可以调用,因此静态方法中不能使用super与this关键字,不能直接

访问所属类的实例变量与实例方法(就是不带static的成员变量与成员方法)[只能访问静态成员变量、静态成员方法]

因为实例成员与特定的对象关联!

而且static方法独立于任何实例,所以方法内容必须是实现的,因此不能使用abstract修饰[不是抽象方法]。

3)形成静态代码块

是在类中独立的代码块,可以在类中的任何位置,可以有多个代码块,不存于任何一个方法体内是独立存在的。JVM加载

时会执行这些代码块,当代码块有多个时按照他们在代码中出现的前后顺序进行加载。


2.final关键字


Java中的final关键字表示‘无法改变的’,它可以修饰非抽象类、非抽象类成员方法、变量。

牢记:

1)final修饰的不能被继承,没有子类,final类中的方法默认是final修饰。

2)final修饰的方法不能被子类覆盖(重写),但可以被继承[相同的方法-一模一样]。

编译器在遇到调用final方法时候会转入内嵌机制,大大提高执行效率。

3)final修饰的成员变量表示常量,只能被赋值一次[初始化赋值],赋值后不能改变。

final修饰的变量有三种:静态变量、实例变量和局部变量。 

另外,final变量定义的时候,可以先声明,而不给初值,这中变量也称为final空白,无论什么情况,编译器都确保空白final在使用之前必须被初始化。

当函数参数为final类型时,你可以读取使用该参数,但是无法改变该参数的值。

4)final不能用于修饰构造方法。

注意:父类的private方法是不能被子类覆盖的,因此private方法默认是final修饰的。


3.static与final一起使用进行修饰

static final 用来修饰成员变量和成员方法,可以理解为“全局常量”。

对于变量,表示一旦给值就不可以修改,并且通过类名可以进行访问。

对于方法,表示不可覆盖,而且通过类名直接访问。

特别要注意一个问题:
        对于被static和final修饰过的实例常量,实例本身不能再改变了,但对于一些容器类型

(比如,ArrayList、HashMap)的实例变量,不可以改变容器变量本身,

但可以修改容器中存放的对象,这一点在编程中用到很多。

引用一个实例代码:

public class TestStaticFinal {         private static final String strStaticFinalVar = "aaa";         private static String strStaticVar = null;         private final String strFinalVar = null;         private static final int intStaticFinalVar = 0;         private static final Integer integerStaticFinalVar = new Integer(8);         private static final ArrayList<String> alStaticFinalVar = new ArrayList<String>();         private void test() {                 System.out.println("-------------值处理前----------\r\n");                 System.out.println("strStaticFinalVar=" + strStaticFinalVar + "\r\n");                 System.out.println("strStaticVar=" + strStaticVar + "\r\n");                 System.out.println("strFinalVar=" + strFinalVar + "\r\n");                 System.out.println("intStaticFinalVar=" + intStaticFinalVar + "\r\n");                 System.out.println("integerStaticFinalVar=" + integerStaticFinalVar + "\r\n");                 System.out.println("alStaticFinalVar=" + alStaticFinalVar + "\r\n");                 //strStaticFinalVar="哈哈哈哈";        //错误,final表示终态,不可以改变变量本身.                 strStaticVar = "哈哈哈哈";                //正确,static表示类变量,值可以改变.                 //strFinalVar="呵呵呵呵";                    //错误, final表示终态,在定义的时候就要初值(哪怕给个null),一旦给定后就不可再更改。                 //intStaticFinalVar=2;                        //错误, final表示终态,在定义的时候就要初值(哪怕给个null),一旦给定后就不可再更改。                 //integerStaticFinalVar=new Integer(8);            //错误, final表示终态,在定义的时候就要初值(哪怕给个null),一旦给定后就不可再更改。                 alStaticFinalVar.add("aaa");        //正确,容器变量本身没有变化,但存放内容发生了变化。这个规则是非常常用的,有很多用途。                 alStaticFinalVar.add("bbb");        //正确,容器变量本身没有变化,但存放内容发生了变化。这个规则是非常常用的,有很多用途。                 System.out.println("-------------值处理后----------\r\n");                 System.out.println("strStaticFinalVar=" + strStaticFinalVar + "\r\n");                 System.out.println("strStaticVar=" + strStaticVar + "\r\n");                 System.out.println("strFinalVar=" + strFinalVar + "\r\n");                 System.out.println("intStaticFinalVar=" + intStaticFinalVar + "\r\n");                 System.out.println("integerStaticFinalVar=" + integerStaticFinalVar + "\r\n");                 System.out.println("alStaticFinalVar=" + alStaticFinalVar + "\r\n");         }         public static void main(String args[]) {                 new TestStaticFinal().test();         } }

运行结果:

-------------值处理前----------strStaticFinalVar=aaastrStaticVar=nullstrFinalVar=nullintStaticFinalVar=0integerStaticFinalVar=8alStaticFinalVar=[]-------------值处理后----------strStaticFinalVar=aaastrStaticVar=哈哈哈哈strFinalVar=nullintStaticFinalVar=0integerStaticFinalVar=8alStaticFinalVar=[aaa, bbb]Process finished with exit code 0
但必须明白:通过static final修饰的容器类型变量中所“装”的对象是可改变的。这是和一般基本类型和类类型变量差别很大的地方。





原创粉丝点击