当了5年的Java程序员,难道还说不清个static的用途吗? 你能全说出来吗?static用在哪里? 下面我为大家提供一个速记的方式,包你记得牢牢的。 首先我们先把一个Java类中所能存在的所有组件都罗列一遍(相信这对大家来说应该是轻而易举的事情),从上到下依次是:包定义 导入模块 类定义 代码块 变量 常量 构造器 方法 内部类 其中可以被static修饰的组件为导入模块 、代码块 、变量 、常量 、方法 、内部类 ,这几个部分。 怎么样,我们只要在脑海中把一个Java类的所有组件过一遍,把其中可被static修饰的组件挑出来就好啦。 至于static修饰各个组件的用途就取决于static单词的本意:静态。 静态在Java中就是不变的意思,主要指的是存储位置不变。 变化主要指创建类的一个新对象时,其内部包含的部分组件会重新在内存中分配创建,相对于已有的对象而言,这些部件的地址就是变化的。 下面我们来看看这几个static修饰组件的用途 静态导入 import static java.math.BigDecimal.*; import static java.math.BigDecimal.ONE; import static java.math.BigDecimal.valueOf; 如上所示,静态导入只能导入目标类中的静态部件 ,如静态变量、静态常量、静态方法等。 如果按照第一行(1)所示的方式导入,则表示导入BigDecimal类中所有的静态部件,这些部件不必再用类名点用,直接使用就行,像第2-3行所示分别时单独导入一个静态常量和静态方法。package com.dh.base; import java.math.BigDecimal; import static java.math.BigDecimal.*; import static java.math.BigDecimal.ONE; import static java.math.BigDecimal.valueOf; public class StaticTest { public static void main(String[] args) { BigDecimal bd = valueOf(1); BigDecimal bd1 = ONE; BigDecimal bd2 = TEN; } } 普通的导入只能导入具体的类 静态代码块 代码块就包括普通代码块和静态代码块两种。 静态代码块是在类加载的时候被执行的,而且只会执行一次。 也就是说静态代码块是跟着类走的,区别于普通代码块是跟着对象走的,每次创建一个新对象的时候都会执行一次。 普通代码块主要作用就是为了初始化一些普通成员变量,或者做一些创建对象的前提工作。静态代码块则主要用于初始化一些静态成员变量,或者做一些类加载时的补充工作。 静态变量 修饰变量应该是static最常见的用途之一。 被static修饰后的变量称为静态变量,一旦一个普通变量被static修饰,那么这个变量就会超脱于具体对象,称为类级别的存在。 什么意思呢?简单说就是静态变量会在类加载的时候分配内存进行保存,而普通变量需要在创建对象的时候才会分配内存空间。 静态变量属于类,可以使用类名点用的方法调用,即使不存在对应的对象,也可以直接使用,普通变量不可以,必须先有对象之后,通过对象来调用。 静态常量 常量和变量的区别仅仅是前者被final修饰。 final表示最终,也有不变的意思,但这个不变指的是值得内容不变。 常量一旦赋值,则值不再改变。 普通常量与静态常量的区别与变量类似。 普通常量在创建对象的时候分配空间保存,静态常量则是在类加载时进行空间分配。 静态方法 修饰方法同样是static最常见的用途之一。 被static修饰的方法称为静态方法。 静态方法同样属于类,普通方法属于对象。 静态方法内部不能直接调用普通方法和普通变量,原因很简单,因为静态方法可以在不存在对象的情况下直接调用,此时没有对象,也就无法调用其名下的普通方法。而在普通方法中则可随意调用普通方法和静态方法。 这就是一个简单的先后问题。 静态内部类 内部类包括成员内部类、静态内部类、匿名内部类、局部内部类四种。 被static修饰的内部类称为静态内部类,主要与成员内部类进行区分。 成员内部类是依赖于外部类存在的,其内部存在一个指向外部类的引用,内部只可以有非静态方法与变量,却可以调用外部类的普通变量与方法、静态变量与方法。 静态内部类脱离了外部类,不存在指向外部类的引用,内部可以有静态方法与变量和非静态方法与变量,且只能调用外部类的静态方法与变量。 二者的创建对象的方式也不一样。具体见下面代码:package com.dh.base; public class StaticTest { String s1 = "普通变量"; static String s = "static变量"; static void staticMethod() { BigDecimal bd = valueOf(1); BigDecimal bd1 = ONE; System.out.println("static方法"); } void method() { System.out.println("普通方法"); } static class staticInnerClass {// 静态内部类 static void innerStaticMethod1() {// 静态方法 // s1 = "111";// 调用外部成员变量-错误 // method();// 调用外部普通方法-错误 s = "222";// 调用外部静态变量-正确 staticMethod();// 调用外部静态方法-正确 } void innerStaticMethod2() {// 非静态方法 // s1 = "111";// 调用外部成员变量-错误 // method();// 调用外部普通方法-错误 s = "222";// 调用外部静态变量-正确 staticMethod();// 调用外部静态方法-正确 } } class innerClass {// 非静态内部类 // static void innerStaticMethod1() { }// 不能存在静态方法 void innerStaticMethod2() {// 非静态方法 s1 = "111";// 调用外部成员变量-正确 method();// 调用外部普通方法-正确 s = "222";// 调用外部静态变量-正确 staticMethod();// 调用外部静态方法-正确 } } public static void main(String[] args) { StaticTest.staticInnerClass staticInnerClass = new StaticTest.staticInnerClass();// 静态内部类-点用 StaticTest.innerClass innerClass = new StaticTest().new innerClass();// 非静态内部类-new新建 } } 好了,就是这些东西,后面东西多了点,其实都挺好了理解,着重理解这个静态的概念就好了。 有了后面的讲述,再结合一开始的速记法,就能够全面记住static的用法用途。