• Java 编程下 static 关键字


    对于每一个基于相同类所产生的对象而言,它们会拥有各自的域成员,然而在某些时候,你会想要这些对象拥有共享的域成员。举个例子来说,在 Ball 类中,打算使用到圆周率 PI 这个数据,因为对于任何一个 Ball 的实例而言,圆周率都是相同的,你不需要让不同的 Ball 实例拥有各自的圆周率域成员。

    1.静态成员变量

    可以将 PI 域成员声明为 static,被声明为 static 的域成员又称静态域成员。静态域成员是属于类所有,而不是个别的对线。可以将静态成员视为每个对象实例所共享的域成员。要声明静态域成员,只要在声明域成员时加上 static 关键字即可。例如:

    public final class Ball {
    
        public static double PI = 3.14159;
        
    }

    静态成员属于类所有,可以在不使用名称参考下,直接使用类名加上运算符来存取静态域成员,不过静态域成员同样遵守 public、protected 与 private 的存取限定。所以若要直接存取静态域成员,必须注意它的权限。例如必须设定为 public 成员,就可以通过以下语句存取:

    System.out.println("PI = " + Ball.PI);

    虽然也可以在声明对象之后,通过对象名称加上.操作符来存取静态域成员,但是这种方式并不被鼓励。通常建议使用类名加上.操作符来存取,这也可以避免于非静态域成员混淆。例如下面的方式是不被鼓励的:

    Ball ball = new Ball();
    System.out.println("PI = " + ball.PI);

    2.静态成员方法

    与静态域成员类似,也可以声明方法成员为 static 方法,又称静态方法。被声明为静态的方法通常是作为工具方法。例如在 Ball 类上增加一个角度转弧度的方法 toRadian():

    public final class Ball {
    
        public static double PI = 3.14159;
    
        public static double toRadian(double angle) {
            return PI / 180 * angle;
        }
    }

    与静态域成员一样,可以通过类名称使用.操作符来存取 static 方法,当然要注意权限设定。例如若设定为 public 可以通过以下语句存取:

    System.out.println("角度 90 等于弧度" + Ball.toRadian(90));

    静态数据与静态方法的作用通常是为了提供共享的数据或工具方法,例如将数学常用数或计算公式,以 static 声明并编写,之后可以把这个类当作工具类。通过类名称来管理与取用这些静态数据或方法,例如 J2SE 所提供的 Math 类上,就有 Math.PI 这个静态常数,以及 Math.Exp()、Math.Log()、Math.Sin() 等静态方法可以直接使用,另外 Integer.parseInt()、Integer.MAX_VALUE 等也都是静态方法与静态域成员的实际例子。

    由于静态成员是属于类而不是对象,所以当调用静态方法时,并不会传入对象的参考,即静态方法中不会有 this 参考名称。由于没有 this 名称,所以在 Java 的静态方法中不允许使用非静态成员。因为没有 this 来引用至对象,也就无法辨别要存取的是哪一个对象的成员,事实上,如果在静态方法中使用非静态域成员,在编译时就会出现以下的错误信息:

    non-static variable test cannot be referenced from a static context

    或者是在静态方法中调用非静态方法,在编译时就会出现以下的错误信息:

    non-static method showHello() cannot be referenced from a static context

    在 Java 中程序入口点(Entry Point)的 main() 方法就是静态方法,如果要直接在 main() 中调用其他的方法,则该方法就必须是静态方法。例如:

    public class Hello {
    
        public static void sayHello() {
            System.out.println("Hello World!");
        }
        
        public static void main(String[] args) {
            sayHello();
        }
        
    }

    可以试着将 sayHello() 前的 static 去掉,编译时就会发生上述的第二个错误信息。

    3.静态代码块

    Java 在使用到类时才会加载类至程序中。如果在加载类时,希望先进行一些类的初始化动作,可以使用 static 定义一个静态区块,并在当中编写类载入时的初始化动作。例如:

    public class Ball {
    
        static {
            
            // 执行初始化程序代码
            
        }
        
        // Methods
        
    }

    在类被加载时,预设会先执行静态区块中的程序代码,且只会执行一次。实际使用范例来说明一下,首先编写范例 SomeClass 类。

    public class SomeClass {
    
        static {
            
            System.out.println("类被载入");
            
        }
        
    }

    这个类只定义了静态区块,主要是为了测试类被加载时是否执行该区块,接着编写测试程序 StaticBlockDemo 类。

    public class StaticBlockDemo {
    
        public static void main(String[] args) {
    
            SomeClass someClass = new SomeClass();
    
        }
    
    }

    在使用 new 来建立 SomeClass 的实例时,SomeClass 类会被加载,加载之后预设会执行静态区块的内容,所以程序的执行结果如下:

    类被载入
    专注移动互联网产品设计研发 分享最新的移动互联网产品和技术
  • 相关阅读:
    Hadoop IO
    HDFS
    简介
    队列
    classLoader和Class.forName的区别
    String为什么是final类型的
    Fabric
    超级账本——面向企业的分布式账本
    以太坊
    pycharm破解教程
  • 原文地址:https://www.cnblogs.com/sunzn/p/3061464.html
Copyright © 2020-2023  润新知