java中的static关键字

Java中的static关键字

一般来说,在Java中,定义类的时候,只是描述这个类的一些成员,行为规则,在还没有new出这个类的实例之前,我们没有办法用这个类去做任何事情,只有在new出这个类的对象时,给这个类分配了存储空间,其方法才供外接使用。 
但是,有两种情况是例外 
- 单独为这个类中的某个域分配特定的存储空间,这样一来,这个域就不用关心该类创建了对少个对象了,深圳不关心这个类有没有创建对象,因为其单独拥有一个存储空间,不会依赖对象的存储空间。 
- 另一种,是该类中的方法不想与这个类的某一个实例拥有太大的联系,而是作为一个单独的存在,使得没有创建这个类的实例时,也能通过类名来调用它。

在定义域或者方法的时候加上static关键字,可以实现以上两种需求。

static的使用

  • 使用static修饰域,以字段为例。
public class TestStatic {
    public static void main(String[] args) {
        /*
         * 对于static变量来说,调用的方法有两种,
         *   一。可以通过通过类名直接调用,
         *   二。可以通过该类的对象进行调用。
         * 两者调用的都是同一个变量,因为它单独处于一个独立的空间,不会因为对象的不同而不同
         * 建议使用第一种调用方法,因为:
         *   可以强调当前变量是一个static变量
         *   从某种角度来说,其有助于编译器进行优化。
         */
        System.out.println(Test.param1);
        System.out.println(Test.param2);

        Test testObject = new Test();
        System.out.println(testObject.param1);
        System.out.println(testObject.param2);
        System.out.println(testObject.param3);

    }
}
class Test {
    /*
     * 定义static字段的时候,只需要在字段定义的类型之前加上一个"static"关键字即可
     */
    public static int param1 = 1;
    public static int param2 = 2;
    public int param3 = 3;
}
  • 使用static 修饰方法
package test;
public class TestStatic {
    public static void main(String[] args) {
        /**
         * 调用静态方法的方式同样有两种
         *   一,通过类名直接调用静态方法
         *   二。通过类的对象调用静态方法
         *  这两者调用的都是同一个静态方法
         */
        System.out.println(Test.add(1));

        Test testObject = new Test();
        System.out.println(testObject.del(1));
    }
}
class Test {
    /*
     * 在定义static方法的时候,只需要在方法类型定义之前加一个"static"关键字。
     */
    public static int add(int param1) {
        return param1 ++;
    }
    public int del(int param1) {
        return param1 -- ;
    }
}

static 方法和 static 变量在jvm中的位置

根据《Java虚拟机规范》的规定,运行时数据区通常包括这几个部分:

  • 程序计数器(Program Counter Register) 
    也有称作为PC寄存器,在汇编中,程序计数器,用来存储程序当前执行指令的地址,当CPU需要执行指令时,需要从程序计数器中得到当前需要执行的指令所在存储单元的地址,然后根据得到的地址获取到指令,在得到指令之后,程序计数器便自动加1或者根据转移指针得到下一条指令的地址,如此循环,直至执行完所有的指令。 
    但是,汇编中知道的程序计数器是一个物理概念,jvm中指的是一个逻辑的概念,但是两者的功能是一样的 
    在设计到多线程的时候,每个线程指的的指令都不一样,所以,在多线程环境中,每个线程都有一个程序计数器。

  • Java栈(VM Stack) 
    Java栈的作用有四个 
    1.用于存储程序中的变量,这里的变量有可能是Java中的基本数据类型的标量,对于这种变量来说,java栈中直接存储了变量的值。还有一种变量是指向对象的引用。在Java中,对象实例存储在Java中,而指向这个对象的引用存储在栈中。 
    2.用于进行数据运算。 
    3.用于存储指向常量池的引用 
    4.用于存储方法的返回地址。

每个线程都拥有自己的栈

  • 本地方法栈(Native Method Stack 
    顾名思义,本地方法栈是执行本地方法的时候用到的栈,而Java栈是执行Java方法的时候用到的栈

  • 方法区(Method Area) 
    在方法区中,存储了每个类的信息,包括: 
    类的名, 
    方法信息, 
    字段信息, 
    静态变量, 
    常量, 
    编译器编译后的代码等。

  • 堆(Heap) 
    在java中,讲类的实例对象放在堆中,堆是所有线程共享的,有java的垃圾回收机制实现垃圾回收。

也就是说,static变量和方法都存储在jvm的方法区中。

原文地址:https://www.cnblogs.com/da-mooo/p/7441263.html