zoukankan      html  css  js  c++  java
  • static

    总结关键字static的用法。
    author: ZJ 2007-3-10
    Blog: [url]http://zhangjunhd.blog.51cto.com/[/url]
    1.关键字static(先记住这些,再往下看)
    1)静态方法和静态变量是属于某一个类,而不属于类的对象。
    2)静态方法和静态变量的引用直接通过类名引用。
    3)在静态方法中不能调用非静态的方法和引用非静态的成员变量。反之,则可以。
    4)静态变量在某种程序上与其他语言的全局变量相类似,如果不是私有的就可以在类的外部进行访问。
    2.何时使用static
    在我们创建一个类的实例时(对象),通常使用new方法,这样这个类的数据空间才会被创建,其方法才能被调用。
         但是,有时候我们希望一个类虽然可以被创建n个对象(显然这n个对象的数据空间是不相同的),但这n个对象的某些数据是相同的,即不管这个类有多少的实例,这些数据对这些实例而言之有一份内存拷贝(见示例1)。这是静态变量的情形。
    另一种情形是,你希望某个方法不与包含它的类的任何对象关联在一起。也就是说,即使没有创建对象,也能够调用这个方法。static 方法的一个重要用法就是在不创建任何对象的前提下,就可以调用它(见示例2)。这是静态方法的情形。
    还有一种特殊的用法出现在内部类中,通常一个普通类不允许声明为静态的,只有一个内部类才可以。这时这个声明为静态的内部类可以直接作为一个普通类来使用,而不需实例一个外部类(见示例3)。这是静态类的情形。
    示例1
    public class TStatic {
        static int i;
     
        public TStatic() {
           i = 4;
        }
     
        public TStatic(int j) {
           i = j;
        }
     
        public static void main(String args[]) {
           System.out.println(TStatic.i);
           TStatic t = new TStatic(5); // 声明对象引用,并实例化。此时i=5
           System.out.println(t.i);
           TStatic tt = new TStatic(); // 声明对象引用,并实例化。此时i=4
           System.out.println(t.i);
           System.out.println(tt.i);
           System.out.println(t.i);
        }
    }
     
    结果:
    0
    5
    4
    4
    4
    static变量在类被载入时创建,只要类存在,static变量就存在。它们在定义时必须进行初始化。上例中没有初始化i,所以会得到默认的初始值0。static的变量的初始化仅能一次,static变量只是接受了最后一次的初始化。
    实际这还是多个实例共享一个静态的变量的问题。
     
    示例2
    未声明为static
    class ClassA {
        int b;
     
        public void ex1() {}
     
        class ClassB {
           void ex2() {
               int i;
               ClassA a = new ClassA();
               i = a.b; // 这里通过对象引用访问成员变量b
               a.ex1(); // 这里通过对象引用访问成员函数ex1
           }
        }
    }
     
    声明为static
    class ClassA {
        static int b;
     
        static void ex1() {}
    }
     
    class ClassB {
        void ex2() {
           int i;
           i = ClassA.b; // 这里通过类名访问成员变量b
           ClassA.ex1(); // 这里通过类名访问成员函数ex1
        }
    }
    在使用静态方法时要注意,在静态方法中不能调用非静态的方法和引用非静态的成员变量(在static方法中也不能以任何方式引用this或super)。理由很简单,对于静态的东西,JVM在加载类时,就在内存中开辟了这些静态的空间(所以可以直接通过类名引用),而此时非静态的方法和成员变量所在的类还没有实例化。
    所以如果要使用非静态的方法和成员变量,可以直接在静态方法中实例化该方法或成员变量所在的类。public static void main就是这么干的。
     
    示例3
    public class StaticCls {
        public static void main(String[] args) {
           OuterCls.InnerCls oi = new OuterCls.InnerCls();// 这之前不需要new一个OuterCls
        }
    }
     
    class OuterCls {
        public static class InnerCls {
           InnerCls() {
               System.out.println("InnerCls");
           }
        }
    }
     
    结果:
    InnerCls
    3.静态初始化
    static定义的变量会优先于任何其它非static变量,不论其出现的顺序如何。静态代码块(在“static{”后面跟着一段代码),是用来进行显式的静态变量初始化,这段代码只会初始化一次,且在类被第一次装载时。看下面示例。
    class Value {
        static int c = 0;
     
        Value() {
           c = 15;
        }
     
        Value(int i) {
           c = i;
        }
     
        static void inc() {
           c++;
        }
    }
     
    class Count {
        public static void prt(String s) {
           System.out.println(s);
        }
     
        Value v = new Value(10);
     
        static Value v1, v2;
        static {
           prt("in the static block of calss Count v1.c=" + v1.c + "  v2.c="
                  + v2.c);
           v1 = new Value(27);
           prt("in the static block of calss Count v1.c=" + v1.c + "  v2.c="
                  + v2.c);
           v2 = new Value();
           prt("in the static block of calss Count v1.c=" + v1.c + "  v2.c="
                  + v2.c);
        }
    }
     
    public class TStaticBlock {
        public static void main(String[] args) {
           Count ct = new Count();
           Count.prt("in the main:");
           Count.prt("ct.c=" + ct.v.c);
           Count.prt("v1.c=" + Count.v1.c + "  v2.c=" + Count.v2.c);
           Count.v1.inc();
           Count.prt("v1.c=" + Count.v1.c + "  v2.c=" + Count.v2.c);
           Count.prt("ct.c=" + ct.v.c);
        }
    }
     
    结果:
    in the static block of calss Count v1.c=0  v2.c=0
    in the static block of calss Count v1.c=27  v2.c=27
    in the static block of calss Count v1.c=15  v2.c=15
    in the main:
    ct.c=10
    v1.c=10  v2.c=10
    v1.c=11  v2.c=11
    ct.c=11
    不管是v,v1还是v2,它们操作的成员变量都是同一个静态变量c。
    在类Count中先初始化v1,v2(static Value v1, v2;),再初始化静态代码块(static{}),最后初始化v。
    
  • 相关阅读:
    Java实现 蓝桥杯 算法提高 特等奖学金(暴力)
    Java实现 蓝桥杯 算法提高 特等奖学金(暴力)
    Java实现 蓝桥杯 算法提高 GPA(暴力)
    Java实现 蓝桥杯 算法提高 GPA(暴力)
    Java实现 蓝桥杯 算法提高 GPA(暴力)
    Java实现 蓝桥杯 算法提高 套正方形(暴力)
    Java实现 蓝桥杯 算法提高 套正方形(暴力)
    第一届云原生应用大赛火热报名中! helm install “一键安装”应用触手可及!
    云原生时代,2个方案轻松加速百万级镜像
    Knative 基本功能深入剖析:Knative Serving 自动扩缩容 Autoscaler
  • 原文地址:https://www.cnblogs.com/deepbreath/p/5015579.html
Copyright © 2011-2022 走看看