黑马程序员—static关键字

来源:互联网 发布:怎么下载同花顺云计算 编辑:程序博客网 时间:2024/05/16 11:00

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

static:

用法:

是一个修饰符,用于修饰成员(成员变量,成员方法)。当成员被静态修饰后,就多了一个调用方式,可以直接被类名调用(类名.静态成员)

特点:

1.随着类的加载而加载。(什么时候类被加载:(1).生成类的对象时,会加载该类及该类的父类。(2).访问该类静态成员时. (3).class.forName("类名").(4).命令行中输入:java 类名 )

2.优先于对象存在。

3.被所有对象所共享。

4.可以直接被类名所调用。


实例变量和类变量的区别:

1.存放位置:

  类变量随着类的加载而存在与方法区(共享区,数据区)中。

  实例变量随着对象的建立而存在与堆内存中。

2.生命周期:

  类变量会随着类的消失而消失。它的生命周期最长。(类被卸载:更换了类加载器或应用程序结束。)

  实例变量随着对象的消失而消失。(当对象没有引用指向它,被垃圾回收。)

static使用注意事项:

1.静态方法只能访问静态成员。(理解:静态先存在,如果类没有被实例化也就没有实例变量、方法。静态方法当然不能访问实例变量和方法。)

2.静态方法中不可以定义this,super关键字。(理解:this就是指调用该法的对象,对象的变量是实例变量,所以静态方法不能访问)

静态有利有弊:

利处:1.对对象的共享数据进行单独空间的存储,节省内存空间,没有必要每个对象中都存储一份。

      2.可以直接被类名调用。

弊端:1.生命周期过长,要选好哪些变量和方法被static,应该是那些大多数对象都有的共同属性。如果static不佳而且过多将是对内存更大的浪费。

      2.访问的局限性。(静态方法只能访问静态变量和方法)


static其他应用:静态代码块

形式:static{

      }

说明:一个类可以使用不包含在任何方法体中的静态代码块,当类被载入时,静态代码块被执行,且只被执行一次

     静态块常用来执行类属性的初始化。

与静态方法区别:静态代码块是类加载时就自动执行的。
        静态方法是被调用的时候才执行的。

深入理解static:

   static与类的加载有密切关系,想要深入理解static需要弄清楚类的加载过程。

在Java中,类加载器把一个类装入Java虚拟机中,要经过三个步骤来完成:装载、链接和初始化,其中链接又可以分成校验、准备和解析三步,除了解析外,其它步骤是严格按照顺序完成的,各个步骤的主要工作如下:

1.装载:查找和导入类或接口的二进制数据;

2.链接:执行下面的校验、准备和解析步骤,其中解析步骤是可以选择的;
    1)校验:检查导入类或接口的二进制数据的正确性;
    2)准备:给类的静态变量分配并初始化存储空间;
    3)解析:将符号引用转成直接引用;
3.初始化:激活类的静态变量的初始化Java代码和静态Java代码块。
    初始化类中属性是静态代码块的常用用途,但只能使用一次。

下面用静态代码块与构造代码块的实例程序来理解static的执行时机:

class Parent{static String name= "parent name"; ;//静态变量//构造代码块{System.out.println("parent block");}//静态构造代码块static{System.out.println("parent static block");}//构造方法Parent(){System.out.println("parent constructor");}}class Child extends Parent{//继承Parent类static String name = "child name";//静态变量//构造代码块{System.out.println("child block");}//静态代码块static{System.out.println("child static block");}//构造方法Child(){System.out.println("child constructor");}}public class Demo2{public static void main(String[] args){new Child();}}

输出结果:

parent static block
child static block
parent block
parent constructor
child bock
child constructor
总结:new Child();要想创建一个类的对象(实例化类),就先加载类,然后调用对应的构造方法。因为Child继承了Parent所以其实例化过程会是这样:

1.加载父类Parent 2.加载类Child 3.调用父类构造方法 4.调用Child类构造方法

而加载类时会处理static修饰的相关代码其中包含了static代码块;构造代码块实际上是构造函数中共用的代码抽取而成,是为了使程序更加精炼,即构造代码块可以看成是将其代码分别加在各个构造函数中:

Parent(){          System.out.println("parent block");          System.out.println("parent constructor");      }  

知道了这些,自然就理解了输出结果。

注意:当用命令行java 类名 加载类jvm会先处理静态代码块然后才调用main方法。验证代码如下:

/*静态代码块与main方法测试程序*/public class Demo{static{System.out.println("静态代码块1");}public static void fun(){System.out.println("静态方法");}public static void main(String[] args){System.out.println("main方法");Demo.fun();}static{System.out.println("静态代码块2");}}

输出结果:

静态代码块1

静态代码块2

main方法

静态方法

原创粉丝点击