黑马程序员--Java学习09--static关键字

来源:互联网 发布:抱枕淘宝 编辑:程序博客网 时间:2024/06/10 23:04

---------------------- ASP.Net+Unity开发.Net培训、期待与您交流! ----------------------

一.static关键字

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

       static修饰的成员变量和成员方法习惯上称为静态变量和静态方法,可以直接通过类名来访问,访问语法为:
类名.静态方法名(参数列表...)
类名.静态变量名
       用static修饰的代码块表示静态代码块,当Java虚拟机加载类时,就会执行该代码块。也就是为其分配相应的内存。

二、实例变量和类变量的区别

       用static修饰的成员变量叫做类变量,我们已经知道:一个类通过使用new运算符可以创建多个不同的对象,这些对象将被分配不同的内存空间,如果类中的成员变量有类变量,那么所有对象的这个类变量都分配给相同的一处内存,改变其中一个对象的这个类变量会影响其它对象的这个类变量,也就是说对象共享类变量。如:

class Takecare {static int x;int y;}class A {Takecare A1=new Takecare();Takecare A2=new Takecare();}

内存模式如图:


如果程序中使用了:A1.x=18;

这时如果输出A1.x和A2.x的值,结果都是18。

    当Java程序执行时,类的字节码文件被加载到内存,如果该类没有创建对象,类的实例成员变量不会被分配内存,但是,类中的类变量被加载到内存时,就分配了相应的内存空间。如果该类创建对象,那么不同对象的实例变量互不相同,及分配不同的内存空间,而类变量不再重新分配内存,所有的对象共享类变量,即所有的对象的类变量是相同的一处内存空间,类变量的内存空间直到程序退出运行才释放所有的内存空间。类变量是与类相关的数据变量,也就是说,类变量是和该类创建的所有对象相关连的变量,改变其中一个对象的这个类变量就同时改变了其他对象的这个类变量。因此,类变量不仅可以通过某个对象访问,也可以直接通过类名访问。实例变量仅仅是和相应的对象关联的变量,也就是说,不同对象的实例变量互不相同,即分配不同的内存空间,改变其中一个对象的实例变量不会影响其他对象的这个实例变量,实例变量可以通过对象访问,不能使用类名访问。

三、实例方法和类方法的区别

        类体中的方法分为实例方法和类方法两种,用static修饰的是类方法。当一个类创建了一个对象后,这个对象就可以调用该类的方法。那么实例方法和类方法有什么区别呢?

       当类的字节码文件被加载到内存时,类的实例方法不会被分配入口地址,当该类创建对象之后,类中的实例方法才分配入口地址,从而实例方法就可以被类创建的任何对象调用执行。需要注意的是,当创建一个对象时,类中的实例方法就分配了入口地址,当再创建对象时,不再分配入口地址,也就是说方法的入口地址被所有对象共享,当所有的对象都不存在时,方法的入口地址才被取消。实例方法必须通过对象来调用,当某个对象调用实例方法时,该方法中出现的成员变量被认为是分配给该对象的成员变量,其中的类变量和其他对象共享,所以,实例方法既可以操作实例变量也可以操作类变量。

      对于类中的类方法,在该类被加载到内存时,就分配了相应的入口地址。从而类方法不仅可以被类创建的任何对象调用使用,也可以直接通过类名调用。类方法的入口地址直到程序退出才被取消。所以Java规定:类方法中出现的成员变量必须是被所有对象共享的类变量,即类方法 不可以操作实例变量,这样规定的原因是:在类创建对象之前,实例成员变量还没有分配内存。类方法也不可以调用其它的实例方法,这是因为在类创建对象之前,实例方法也没有入口地址。

     无论是类方法或实例方法,当被调用执行时,方法中的局部变量才被分配内存空间,方法调用完毕,局部变量即刻释放所占的内存。在一个方法被调用执行完毕之前,如果该方法又被调用,那么,方法的局部变量会再次被分配新的内存空间,比如,方法在递归调用时,方法中的局部变量会在次被分配新的内存空间。

例:计算出Fibinacii数列的第7项

class Fibi {public static long fibinacii(int n) {long c=0;if (n==1||n==2) {c=1;}else {c=fibinacii(n-1)+fibinacii(n-2);}return c;}}public class Test {public static void main(String[] args) {System.out.println(Fibi.fibinacii(7));}}

---------------------- ASP.Net+Unity开发.Net培训、期待与您交流! ----------------------


0 0
原创粉丝点击