理解Java中静态的概念1

       

       首先,先来说明下java中动静态的概念的来源。因为java虚拟机对内存空间的分配有动态和静态之分。其实这里的静态分配就是提前分配好一块固定的内存来存储一种变量,这种变量就是所谓的静态变量,它由static修饰成为静态变量。这就是静态的概念来源,其实就是提前分配固定的空间的意思。之前,我一直不明白为什么叫静态,后来我反复琢磨之后,认为他所谓的静态就是指这个,而对应的动态的概念则是说当程序运行到某个类的实例对象或者其实例变量时再分配内存空间的意思。这样一看,动态和静态的概念其实就是区分程序中运行的变量或方法等是否是提前分配好内存空间所起的名词和说法。不看程序跟与之交互的硬件--内存和硬盘之间的关系,很难理解这个静态和动态的概念。至此,我看了很多大牛的博客,又通过自己的思考加工,终于搞明白这是怎么一回事。也算是没白看那么多文章和博客。

      接下来就说下java中跟静态有关的类、变量、方法和函数等的使用。

      我看了很多文章,都是转载别人的好文章,但是没有一篇文章把这些东西总结起来,给人一个整体的概念。我就一直是糊里糊涂的,对这块。现在我看了那么多文章后,对静态这个概念有了更好的理解,就想把它写下来,便于我整理和巩固对技能的认识、理解,也便于像之前的我一样懵懵懂懂的人理解和掌握这个java的一个特性。

      总的来说,java中跟静态有关的名词有类、变量、方法、函数和代码块。怎样代表它们是静态的呢,在其修饰符前面加上static就是静态的意思。

      下面分别讲述这几种名词的概念和用法。

      1、静态

      静态类的使用不多。

      2、静态变量

      静态变量就是类中在数据类型前有static作修饰的变量。静态变量的特点是 在java虚拟机加载程序时就初始化其值,这里要说明一下。因为静态变量的类型有2种,一种是8种基本数据类型的一种,一种是引用类型的引用。

     那对静态变量的初始化就分别按其类型的默认初始值来初始化,8种基本数据类型的默认初始值都是0,引用类型的默认初始值都是null。

     这里得提下Java类的生命周期。java类的生命周期有5个阶段,装载(加载)、连接、初始化、使用和卸载

     

这里得讲解下各个阶段的工作内容。

1)加载。很多人应该知道,我们每次写完java代码都会生成一个对应的.class文件,这是java虚拟机运行的基础,因为它只能识别这种文件。而java类文件经过编译后,就是.class文件。java类的生命周期就是.class文件从加载到消亡的过程。

    加载的意思,就是通过.class文件找到类的信息将其加载到方法区中,然后在堆区中实例化一个java.lang.Class对象,作为方法区中这个类的信息的入口。但是,这一功能是在jvm之外实现的,主要的原因是方便应用程序让应用程序自己决定如何获取这个类,在不同的虚拟机实现的方式不一定相同。hotspot虚拟机是采用在使用时再加载的方式,也有其他是预先加载的。

2)连接。连接一般是加载和初始化阶段交叉进行,过程由以下三部分组成。

    a)验证:确定该类是否符合java语言的规范,有没有属性和行为的重复,继承是否合理,总之,就是保证jvm能够执行。

    b)准备:主要作的就是为由static修饰的成员变量分配内存,并设置默认的初始值。

      默认初始值如下:

         1. 8种基本数据类型的默认初始值是0

         2. 引用类型的默认初始值是null

         3. 由static final 修饰的变量会直接赋值,如static final int a=10; 则默认就是10.

    c) 解析:这一阶段的任务就是把常量池中的符号引用转换为直接引用,说白了就是jvm会将所有的类或接口名、字段名、方法名转换为具体的内存地址。也就是分配内存空间的过程。

  3)初始化。初始化这一阶段就是将将静态变量(类变量)赋值的过程,即只有被static修饰的才能被初始化。执行的顺序是:父类静态域或静态代码块,然后是子类静态域或子类静态代码块(静态代码块先被加载,然后才是静态属性)。

  4)使用。在类的使用过程中,依然存在以下3步。

       a) 对象实例化:就是执行类中构造函数的内容。如果该类存在父类,JVM会通过显式或隐式 的方式先执行父类的构造函数,在堆内存中为父类的实例变量开辟空间,并赋予默认的初始值,然后再根据构造函数的代码内容将真正的值赋予实例变量本身,然后引用变量获取对象的首地址,通过操作对象来调用实例和方法。

       b) 垃圾收集:当对象不再被引用的时候,即程序执行完毕,就会被虚拟机标上特别的垃圾记号,在堆中等待GC回收。

       c) 对象的终结:当对象被GC回收后,对象就不再存在,对象的生命也就走到了尽头。

  5)类卸载。类卸载即类的生命周期走到了最后一步,程序中不再有该类的引用,该类也就会被jvm执行垃圾回收,从此生命结束。

   代码示例:

class A{

    static int a;//类变量,即静态变量

    String name;

    int id;

    //静态代码块

    static{

        a=10;

        System.out.println("这是父类的静态代码块"+a);

    }

    //构造代码块

    {

        id=11;

        System.out.println("这是父类的构造代码块id:"+id);

    }

    A(){

        System.out.println("这是父类的无参构造函数");

    }

    A(String name){

        System.out.println("这是父类的name"+name);

    }

}

 

class B extends A{

    String name;

    static int b;

    static{

        b=12;

        System.out.println("这是子类的静态代码块"+b);

    }

     B(String name) {

        super();

        this.name = name;

        System.out.println("这是子类的name:"+name);

    }

}

public class Test666 {

public static void main(String[] args) {

    B bb=new B("GG");

}

}

      3、静态方法,就是静态函数。

       比如 public class Test{

               int a;

               int b;

              public static int sum(int x, int y)

             { return x+y; }

             public int add(int x, int y)

             { return x+y; }   }

      调用静态方法不用实例化类,直接采用类名.静态方法名的方式即可。

     public class testSum{

            int sum;

           public static void main(String[] args)

           {   sum=Test.sum(4,5);

               System.out.println(sum);

               Test t=new Test(); //这里因为add()方法不是静态方法,所以必须先实例化Test类,才能调用它。

               sum=t.add(4,5);

               System.out.println(sum);

          }

      4、静态代码块

         静态代码块是用static修饰的一块代码。它不同于静态函数,有参数。静态代码块是没有参数的。只是为了实现一些需要提前加载的功能。

         静态代码在类的初始化阶段被初始化。

         非静态代码则在类的使用阶段(也就是实例化一个类的时候)才会被初始化。

         static {

              //静态代码块

         }

         静态代码块主要用于类的初始化。只执行一次,并且在同属于一个类的main函数之前执行。

         静态代码块的特点有:静态代码块会在类被加载时自动执行;

         静态代码块只能定义在类里,不能定义在方法中。

         静态代码块里的变量都是局部变量,只在块内有效。

         一个类中可以定义多个静态代码块,按顺序执行。

         静态代码块只能访问类的静态成员,而不允许访问实例成员。

    5、静态代码块和静态函数的区别:

        静态代码块:一般情况下,如果有些代码必须在项目启动前执行,需要使用静态代码块,这种代码是主动执行的,它只执行一次,并且在同属一个类的main函数之前执行。

        静态函数:需要在项目启动的时候就初始化,在不创建对象的情况下,其他程序来调用的时候,需要使用静态方法,这种方法是被动执行的。

    6、注意:

         1)静态变量是属于整个类的变量而不是属于某个对象的。注意不能把任何方法(函数)体内的变量声明为静态,例如:
      fun()
     {
       static int i=0;//非法。
     }

         2)一个类可以使用不包含在任何方法体中的静态代码块,当类被载入时,静态代码块被执行,且只被执行一次,静态块常用来执行类属性的初始化。例如:
   static
  {
  }

  7、主程序类中的的静态变量先于静态代码块初始化,其后进入主函数类(程序入口处,即main函数),其后根据静态函数的调用情况,才能选择性的初始化

 

      

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值