JAVA基础(005_static关键字)

static关键字:在 Java 中,static 表示“全局”或者“静态”的意思,用来修饰成员变量成员方法以及代码块

1. static变量:
static 修饰的变量称为静态变量,没有用 static 修饰的变量称为实例变量。静态变量不依赖于实例对象存在,在内存中只有一份。

2. static方法:
static 修饰的方法称为静态方法,通过类名直接调用。静态方法在类加载的时候就存在,它不依赖于任何实例且不能是抽象方法(abstract method)。

3. static 代码块
被 static 修饰的代码块称为静态代码块,静态代码块会随着类的加载一块执行,它可以存在于该类的任何地方。

模拟Math类(除静态代码块部分,余下代码均copy自jdk源码):

  1. Math类被final关键字修饰,表示该类为最终类,不能被继承。
  2. 私有构造函数,表示Math类不能被实例化。(Do not let anyone instantiate this class. 不能让任何人实例化这个类,即使你有钱,有权,长相俊美也不行)
  3. 相对于jdk而言,Math类中的所有方法均为静态方法。
public final class Math {

    // 静态变量
    public static final double PI = 3.14159265358979323846;

    /**
     * Don't let anyone instantiate this class.
     */
    private Math() {} // 私有构造函数,即Math类不能被实例化。

    // 静态方法
    public static int max(int a, int b) {
        return (a >= b) ? a : b;
    }

    // 静态代码块
    static {
        System.out.println("静态代码块");
    }
}

测试代码:

public class MainClass {

    public static void main(String[] args) {

        // 调用静态变量
        System.out.println("PI: " + Math.PI);

        // 调用静态方法
        int res = Math.max(8, 6);
        System.out.println("max: " + res);
    }
}

测试结果:

PI: 3.141592653589793
静态代码块
max: 8

测试结果

例题1:通过this访问静态变量。

public class MainClass {

    private static int v = 10; // 静态变量

    public static void main(String[] args) {
        new MainClass().print(); // this表示当前实例对象
    }

    public void print() {

        // The value of the local variable v is not used
        int v = 20; // 局部变量

        // The static field MainClass.v should be accessed in a static way
        System.out.println("value: " + this.v); // this访问静态变量
    }
}

测试结果:

value: 10

测试结果

例题2:构造函数、(静态)代码块的执行顺序。

(一)

public class Base {

    public Base() {
        System.out.println("Base 构造函数");
    }

    // 代码块
    {
        System.out.println("Base 代码块");
    }
}

public class MainClass extends Base {

    public MainClass() {
        System.out.println("MainClass 构造函数");
    }

    // 代码块
    {
        System.out.println("MainClass 代码块");
    }

    public static void main(String[] args) {
        new MainClass();
    }
}

测试结果:

Base 代码块
Base 构造函数
MainClass 代码块
MainClass 构造函数

测试结果-代码块

(二)

public class Base {

    public Base() {
        System.out.println("Base 构造函数");
    }

    // 静态代码块
    static {
        System.out.println("Base 静态代码块");
    }
}

public class MainClass extends Base {

    public MainClass() {
        System.out.println("MainClass 构造函数");
    }

    // 静态代码块
    static {
        System.out.println("MainClass 静态代码块");
    }

    public static void main(String[] args) {
        new MainClass();
    }
}

测试结果:
Base 静态代码块
MainClass 静态代码块
Base 构造函数
MainClass 构造函数

测试结果-静态代码块

(三)

public class User {

    public User() {
        System.out.println("User 构造函数");
    }

    // 静态代码块
    static {
        System.out.println("User 静态代码块");
    }
}

public class MainClass extends Base {

    public MainClass() {
        System.out.println("MainClass 构造函数");
    }

    // 静态代码块
    static {
        System.out.println("MainClass 静态代码块");
    }
}

public class Base {

    // 成员变量
    public User user = new User();

    public Base() {
        System.out.println("Base 构造函数");
    }

    // 静态代码块
    static {
        System.out.println("Base 静态代码块");
    }

    // main方法
    public static void main(String[] args) {
        System.out.println("main方法");
        new MainClass();
    }
}

测试结果:

Base 静态代码块
main方法
MainClass 静态代码块
User 静态代码块
User 构造函数
Base 构造函数
MainClass 构造函数

执行结果分析:

  1. 在Java中,main(String[] args)方法是Java应用程序的入口方法,也就是说,程序在运行的时候,第一个执行的方法就是main(String[] args)方法。但是,在(三)中,执行main(String[] args)方法之前需要加载Base类,如果类中有静态代码块,则首先执行静态代码块,于是打印出“Base 静态代码块”
  2. Base类加载完成之后(Base类中的静态代码块已经执行完成),开始执行main(String[] args)方法,于是打印出“main方法”
  3. 在main(String[] args)方法中执行“new MainClass();”语句对MainClass类进行实例化,在实例化MainClass类之前需要加载MainClass类,如果类中有静态代码块,则首先执行静态代码块,于是打印出“MainClass 静态代码块”
  4. 因为Base类是MainClass类的父类,所以实例化MainClass类之前将首先需要初始化Base类(父类)的成员变量,再调用Base类(父类)的构造函数。初始化Base类(父类)的成员变量就必须先加载User类,如果类(User类)中有静态代码块,则首先执行静态代码块,于是打印出“User 静态代码块”
  5. 在User类加载完成之后(User类中的静态代码块已经执行完成),将调用User类的构造方法,于是打印出“User 构造函数”
  6. User类的构造方法执行完成,即Base类中的成员变量初始化完成,则调用Base类的构造方法,于是打印出“Base 构造函数”
  7. Base类的构造方法执行完成,即父类的构造方法执行完成之后再调用子类(MainClass类)的构造方法,于是打印出“MainClass 构造函数”,进而生成MainClass实例对象。

测试结果

(四)

public class MainClass {

    // 静态代码块
    static {
        System.out.println("MainClass 静态代码块1");
    }

    // main函数
    public static void main(String[] args) {

    }

    // 静态代码块
    static {
        System.out.println("MainClass 静态代码块2");
    }
}

测试结果:

MainClass 静态代码块1
MainClass 静态代码块2

官方文档:
http://docs.oracle.com/javase/8/docs/api/index.html
参考网址:
http://www.cnblogs.com/dolphin0520/p/3799052.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值