• Java基础系列--static关键字


    原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/8477914.html

    一、概述

      static关键字是Java诸多关键字中较常使用的一个,从其本意可得其意:静态,何为静态呢?静,即不动,静止,固定不变之意(其实可以理解为存储位置不变)。

      Java中的静是相对于“动”而言的,所谓的动就是可变化的内容。

      当然这里指的是针对类而言的,静态内容指的是在类被JVM加载的时候就确定的内容,这部分内容只会被分配一次内存,即在内存中保留一份存储,动态内容则不同,它们是随类的对象创建而动的,每当创建一个对象的时候就会对这些内容分配一份内存,即每个对象都有自己独有的内存存储空间(其中保存着那些动态的内容)。

      静态的内容是属于类的,动态的内容属于对象。

      上面的描述是及其概括的描述,下面我们仔细的了解下static的作用。

    二、作用

    2.1 static修饰变量

      static是一种修饰符,最常用的就是修饰变量,static修饰的变量含有全局的意味,这个变量会变得脱颖而出,不再受对象的桎梏,它在类加载的时候就会分配内存来存储,存储在运行时数据区中的方法区中,属于类级别的存在,可以使用类名点用。

      如果我们在类StaticTest中定义一个如下的静态变量:

    1     static int i = 1;//申明静态变量

      那么我们就可以使用下面的方式进行使用:

    1     StaticTest.i = 3;//类名点用

      静态变量可被其他方法直接调用,因为静态变量早于或同于其他变量、方法而存在,故而可被随意使用,但非静态变量不可以,因为非静态变量属于对象,需要在对象创建的时候才能分配内存而存在,明显在对象创建之前静态方法就无法直接调用非静态变量(因为尚不存在这个变量),当然在创建了对象之后就可以调用了,为了确保正确性,一律规定在静态方法中不能直接调用非静态变量,所有的非静态变量必须使用对象来调用。

      何时使用static变量呢?

      根据static变量的储存方式,我们可以看出,这种变量只会存在一份,但却可以被任意使用,可以被所有的对象所拥有,它的值的可变的,但却是共享的,一方改变,多方共享。

      那么我们不难想到,我们在定义类的时候对于那些公共的、共享的属性完全可以定义成static的,这样一来,不但节省的内存消耗,而且操作性也变得非常容易,需要修改的时候,只需要修改一个,那么所有对象都会得到这个修改后的新值。

    2.2 static修饰常量

      常量是被final所修饰的变量的别称,final修饰变量之后,表示这个变量的值一旦赋值,则不再发生改变。如果在加上static修饰,那么这个变量就会变成一个静态常量(类常量),这个常量会在类加载时分配内存到方法区中。而仅使用final修饰的常量则是在对象创建时保存到方法区中。因为他属于对象的常量,而静态常量是属于公共的、共享的常量。

      具体可以查看《Java基础系列--final、finally关键字

    2.3 static修饰方法

      static修饰方法表示这些方法为静态方法,静态方法和非静态方法一样都保存在方法区中,不同之处在于动静之分,静态方法中不能直接调用非静态变量和方法。静态方法自身属于类级存在,可以使用类名点用。

      近来,static方法一般用于定义工具方法,一般在一个工具类中定义,这个类内部全部为静态内容,完全作为一个工具对外进行服务(这貌似有些违背面向对象设计思想)。

    2.4 static修饰代码块

      代码块的存在,一般用于初始化一些变量的值,非静态代码块用于初始化非静态变量的值,该代码块在每次创建对象时都会被调用,而静态代码块用于初始化一些静态变量的值,只会在类加载的时候调用执行一次。

    2.5 static修饰内部类

      内部类种类较多,这里讲静态内部类,静态内部类由于其静态特性,可脱离外部类来创建对象,普通内部类必须依据外部类对象来创建内部类对象。

      静态内部类中可调用外部类中的静态内容,其中包括private内容。

     1 class Invoke{
     2     static int i = 1;
     3     int j = 2;
     4     static class InnerClass1{
     5         public void innerMethod(){
     6             i = 3;
     7             new Invoke().j = 4;
     8             outMethod1();
     9 //            outMethod2();//报错
    10 //            j = 4;//报错
    11         }
    12     }
    13     class InnerClass2{
    14         public void innerMethod(){
    15             i = 3;
    16             outMethod1();
    17             outMethod2();
    18             j = 4;
    19         }
    20     }
    21     static void outMethod1(){}
    22     void outMethod2(){}
    23 }

      我们需要使用如下方式创建内部类的对象:

    1 public class StaticTest {
    2     public static void main(String[] args){
    3         Invoke.InnerClass1 innerClass1 = new Invoke.InnerClass1();
    4         Invoke.InnerClass2 innerClass2 = new Invoke().new InnerClass2();
    5     }
    6 }

      注意第3、4行的创建方式的区别。

      静态内部类和普通内部类的区别:

      (1)静态内部类可以有静态成员(方法,属性),而非静态内部类则不能有静态成员(方法,属性)。

      (2)静态内部类只能够访问外部类的静态成员,而非静态内部类则可以访问外部类的所有成员(方法,属性)。

    2.6 static导入

      静态导入功能是一种较新的功能,可以单独导入某个类中的静态方法。

    1 import static java.util.Collections.*;
    2 import static java.util.Collections.synchronizedList;

      如上第一行表示导入Collections类中的所有静态方法,而第二行仅仅导入指定的静态方法synchronizedList()。

  • 相关阅读:
    Ubuntu,QT5连接MySQL
    QT添加程序图标及窗口图标
    动态库与静态库
    Windows Gdi & CDC和HDC的区别与转换
    MFC多线程各种线程用法 .
    MFC 使用控制台打印程序信息
    Windows程序员必须知道的字符编码和字符集
    MFC DestroyWindow、OnDestroy、OnClose 程序关闭相关
    Windows消息机制详解
    c c++ 宏定义中#, ##, #@的含义
  • 原文地址:https://www.cnblogs.com/V1haoge/p/8477914.html
Copyright © 2020-2023  润新知