〇、写在前言
2020.8.29
今天整理了在《Java核心技术 卷Ⅰ》中最基础的static知识,另外补充了一些华东师范大学《Java核心技术》Mooc上的相关内容。楼主目前是一名准大二学生,希望能与你们一同进步呀~
static的作用真的非常简单,只有一句话:它表示属于类而不属于任何类对象的变量和函数。(这里先没有讨论静态内部类)
不要去纠结“静态”这个名称的含义,这只是一种延用的叫法。
**
一、静态字段(类字段)
**
1、静态字段是属于类的字段,它不属于该类的任何对象。
举例:
class Employee{
private static int nextId = 1;
private int id;
...
}
对上述Employee类而言,每个对象都有一个id值,但所有对象只共享一个静态字段nextId。
2、即使一个类没有声明任何对象,静态字段仍然存在。
3、声明为静态的字段可以由类名直接调用,也可以由对象进行调用。
4、类的每个对象都可以修改属于类的公共字段。
二、静态常量
1、静态常量需要在静态变量的基础上加上final关键字,这样可以避免被修改。
举例:Math类中的PI
public class Math{
...
public static final double PI = 3.14159265358979323846;
...
}
2、静态常量的好处是,当你需要使用一个静态常量时,不需要构建类的一个对象,可以直接由类直接调用(此例中即Math.PI);此外,这种做法不会使每一个Math的对象都有一个PI副本。
三、静态方法
1、静态方法无需声明对象,因此它也不是在对象上执行的方法。
2、静态方法不设置有隐式参数(即this)。
3、由于不是在对象上执行操作,静态方法禁止访问非静态的实例字段(如上例中的id),但允许访问类中的静态实例字段(如上例中的nextId与PI)
举例:
public static int getNextId(){
return nextId;//访问了静态字段
}
//使用方法:
int n = Employee.getNextId();//由类名直接调用函数
int m = Math.pow(2,3);
4、静态方法允许被对象调用,但不推荐这样的方式。
Employee harry = new Employee();
harry.getNextId();//合法但不推荐
四、关于main()方法
1、由于在启动程序时没有任何对象,因此main是一个静态方法。
2、每一个类都可以有一个main方法。可以借此对每一个类单元进行测试。
// 假定Employee类是属于Application的一个子类。两个类都定义了
一个main方法。
当命令行运行 java Application时,执行App中的main方法。
当命令行允许 java Employee时, 只执行Emp中的main方法。
五、静态的初始化块
1、什么是初始化块?
初始化块是将类中数据字段初始化的一种方法。
举例:
class Employee
{
private static int nextId;
private int id;
private String name;
private double salary;
//初始化块
{
id = nextId;
nextId++;
}
//构造函数
public Employee()
{
name = "";
salary = 0;
}
...
}
2、什么是静态初始化块?
静态初始化块是用来初始化静态字段的的初始化块。
// 初始化静态字段
private static int nextId = 1; //方法一:声明时初始化
static
{
var generator = new Random();
nextId = generator.nextId(10000);
} //方法二:使用静态初始化块
此种方法仅适用于静态字段初始化代码较为复杂的时候。
3、非静态初始化块(匿名代码块)、静态初始化块、构造函数的执行顺序如下:
(i)若类中存在静态初始化块,则先执行静态初始化块。
(ii)若构造器的第一行调用了另一个构造器,则执行该构造器。
(iii)否则,
a)先将数据字段初始化为默认值(0、false或null)
b)按类中出现的顺序依次赋值或执行各个匿名代码块
(iiii)最终执行构造器主体代码。
注意:
(i)过程仅在加载类的时候执行一次。
(ii)(iii)(iiii)过程每次new出对象均需执行一次。
---------------------------------------没了-----------------------------------------