zoukankan      html  css  js  c++  java
  • Java static关键字与静态块

    一.static修饰符

    static 修饰符能够与属性、方法和内部类一起使用,表示是“静态”的。

    类中的静态变量和静态方法能够与“类名”一起使用,不需要创建一个类的对象来访问该类的静态成员。所以static修饰的变量又称作“类变量”。这与实例变量不同。实例变量总是用对象来访问,因为它们的值在对象和对象之间有所不同。

    下列示例展示了如何访问一个类的静态变量:
    class StaticModifier {
        static int i = 10;
        int j;
        StaticModifier() {
            j = 20;
        }
    }
    public class Test {
        public static void main(String args[]) {
            System.out.println("类变量 i=" + StaticModifier.i);
            StaticModifier s = new StaticModifier();
            System.out.println("实例变量 j=" + s.j);
        }
    }
    上述程序的输出是:
    类变量 i=10
    实例变量 j=20

    二.static属性的内存分配

    在上面的例子中,无需创建类的对象即可访问静态变量 i。之所以会产生这样的结果,是因为编译器只为整个类创建了一个静态变量的副本,因此它能够用类名进行访问。也就是说:一个类中,一个 static 变量只会有一个内存空间,虽然有多个类实例,但这些类实例中的这个static 变量会共享同一个内存空间。示例如下:
    public class Test {
        public static void main(String[] args) {
            UserModel um1 = new UserModel();
            um.userName = "张三";
            um.country = "china";
            UserModel um2 = new UserModel();
            um2.userName = "李四";
            um2.country = "中国";
            System.out.println("um1.userName==" + um1.userName +" um1.country==" + um1.country );
            System.out.println("um2.userName==" + um2.userName +" um2.country==" + um2.country );
        }
    }
    class UserModel {
        public static String country
        public String userName;
    }
    运行结果:
    um1.userName==张三 um1.country==中国
    um2.userName==李四 um2.country==中国

    为什么会是一样的值呢?就是因为多个UserModel 实例中的静态变量country 是共享同一内存空间,um1.country 和 um2.country 其实指向的都是同一个内存空间,所以就得到上面的结果了。

    在对象um2创建前的运行后内存分配示意图如下:


    在对象um2创建后的运行后内存分配示意图如下:


    要想看看是不是 static 导致这样的结果,你可以尝试去掉country前面的 static,然后再试一试,看看结果,应该如下:
        um1.userName==张三 um1.country==china
        um2.userName==李四 um2.country==中国
    还有一点也很重要:static 的变量是在类装载的时候就会被初始化。也就是说,只要类被装载,不管你是否使用了这个static 变量,它都会被初始化。

    小结一下:类变量(class variables)用关键字 static 修饰,在类加载的时候,分配类变量的内存,以后再生成类的实例对象时,将共享这块内存(类变量),任何一个对象对类变量的修改,都会影响其它对象。外部有两种访问方式:通过对象来访问或通过类名来访问。

    三.static的基本规则

    有关静态变量或方法的一些要点如下:

    • 一个类的静态方法只能访问静态属性;
    • 一个类的静态方法不能够直接调用非静态方法;
    • 如访问控制权限允许,static 属性和方法可以使用对象名加“.”方式调用;当然也可以使用实例加“.”方式调用;
    • 静态方法中不存在当前对象,因而不能使用“this”,当然也不能使用”super”;
    • 静态方法不能被非静态方法覆盖;
    • 构造方法不允许声明为 static 的;
    • 局部变量不能使用static修饰。

    static 方法可以用类名来访问,如:
    public class GeneralFunction {
        public static int addUp(int x, int y) {
            return x + y;
        }
    }
    public class UseGeneral {
        public void method() {
            int a = 9;
            int b = 10;
            int c = GeneralFunction.addUp(a, b);
            System.out.println("addUp() gives " + c);
        }
    }
    因为 static 方法不需它所属的类的任何实例就会被调用,因此没有 this 值。结果是,static方法不能访问与它本身的参数以及 static 变量之外的任何变量,访问非静态变量的尝试会引起编译错误。

    注:非静态变量只限于实例,并只能通过实例引用被访问。

    四.静态初始器——静态块

    静态初始器(Static Initializer)是一个存在与类中方法外面的静态块。静态初始器仅仅在类装载的时候(第一次使用类的时候)执行一次。静态初始器的功能是:往往用来初始化静态的类属性。

    示例:
    class Count {
        public static int counter;
        static {// 只运行一次
            counter = 123;
            System.out.println("Now in static block.");
        }
        public void test() {
            System.out.println("test method==" + counter);
        }
    }
    public class Test {
        public static void main(String args[]) {
            System.out.println("counter=" + Count.counter);
            new Count().test();
        }
    }
    运行结果是:
    Now in static block. counter=123
    test method==123

    五.静态import

    当我们要获取一个随机数时,写法是:
    public class Test {
        public static void main(String[] args) {
            double randomNum = Math.random();
            System.out.println("the randomNum==" + randomNum);
        }
    }
    从 JDK5.0 开始可以写为:
    import static java.lang.Math.random;
    public class Test {
        public static void main(String[] args) {
            double randomNum = random();
            System.out.println("the randomNum==" + randomNum);
        }
    }
    静态引用使我们可以象调用本地方法一样调用一个引入的方法,当我们需要引入同一个类的多个方法时,只需写为“import static java.lang.Math.*”即可。这样的引用方式对于枚举也同样有效。

  • 相关阅读:
    GIS 中生成平头缓冲区的方法
    arcengine中图层路径的访问与修改
    Codeforces B. Nearest Fraction运行结果与codeblocks运行结果不一致,求大神指教
    html5各种页面切换效果和模态对话框
    java配置数据库连接池
    android动态壁纸调用
    cocod2d 兼容iphone/ipad 问题
    地方房产网站seo优化完善 提高流量和权重
    Python3.x实现网页登录表单提交功能
    进程地址空间的布局(整理)
  • 原文地址:https://www.cnblogs.com/chateldon/p/3053296.html
Copyright © 2011-2022 走看看