一、static
1、引入
当我们编写一个类时,其实就是在描述其对象的属性和行为,而并没有产生实质上的对象,只有通过new关键字才会产生出对象,这时系统才会分配内存空间给对象,其方法才可以供外部调用。
我们有时候希望无论是否产生了对象或无论产生了多少对象的情况下, 某些特定的数据在内存空间里只有一份,例如所有的中国人都有个国家名称,每一个中国人都共享这个国家名称,不必在每一个中国人的实例对象中都单独分配一个用于代表国家名称的变量。
2、类属性、类方法的设计思想
(1)类属性作为该类各个对象之间共享的变量。 在设计类时,分析哪些属性不因对象的不同而改变,将这些属性设置为类属性。相应的方法设置为类方法。
(2)如果方法与调用者无关,则这样的方法通常被声明为类方法,由于不需要创建对象就可以调用类方法,从而简化了方法的调用。
3、概述
static 的意思的静态的,也是一种修饰符。
用 static 关键字修饰的,属于类,就可以不依靠创建对象来调用了。
关于 static 关键字的使用,它可以用来修饰的成员变量和成员方法,被修饰的成员是属于类的,而不是单单属于某个对象的。
3、使用范围
可以使用 static 修饰: (1)属性、(2)方法、(3)代码块、(4)内部类
4、被修饰后的成员具备以下特点
(1)随着类的加载而加载;
(2)优先于对象存在;
(3)修饰的成员,被所有对象所共享;
(4)访问权限允许时,可不创建对象,直接被类调用;
二、静态变量(类变量)
1、静态变量 VS 非静态变量
按照成员变量是否被 static 修饰,可分为 静态变量(类变量) 与 非静态变量(实例变量)
实例变量:当创建了类的多个对象,每个对象都独立的拥有一套类中的非静态属性。当修改其中一个对象中的非静态属性时,不会导致其他对象中同样的属性值的修改。
类变量:当创建了类的多个对象,多个对象共享同一个静态变量。当通过某一个对象修改静态变量时,会导致其他对象调用此静态变量时,是修改过了的。
2、类变量的特点
(1)当 static 修饰成员变量时,该变量称为 类变量。该类的每个对象都共享同一个类变量的值;
(2)用 static 修饰的成员变量的值,存储在方法区中;static 修饰的成员变量的 get/set 也是静态的;
(3)任何对象都可以更改该类变量的值,但也可以在不创建该类的对象的情况下对类变量进行操作;
(4)如果在方法中有局部变量与 static 修饰的成员变量同名时,在静态变量前面加 "类名." 进行区别(这里不能使用this关键字);
(5)static 不能修饰局部变量;
(6)静态变量随着类的加载而加载。可以通过"类.静态变量"的方式进行调用;
(7)静态变量的加载要早于对象的创建;
(8)由于类只会加载一次,则静态变量在内存中也只会存在一份:存在方法区的静态域中。
定义格式:
static 数据类型 变量名;
Demo:
1 public class Student {
2 private String name;
3 private String age;
4 private int sid;
5 private static int id = 1000;
6
7 public Student(String name, String age) {
8 super();
9 this.sid = ++id; //给学生分配学号
10 this.name = name;
11 this.age = age;
12 }
13 public String getName() {
14 return name;
15 }
16 public void setName(String name) {
17 this.name = name;
18 }
19 public String getAge() {
20 return age;
21 }
22 public void setAge(String age) {
23 this.age = age;
24 }
25 public static int getId() {
26 return id;
27 }
28 public static void setId(int id) {
29 Student.id = id;
30 }
31
32 }
3、类变量与实例变量内存解析
(1)
(2)static 修饰的内容
① static 修饰的内容是随着类的加载而加载的,且只加载一次;
② 存储在一块固定的内存区域(静态区),所以,可以直接被类名调用;
③ 它优先于对象存在,所以,可以被所有对象共享。
图解:
三、静态方法(类方法)
1、类方法
(1)当 static 修饰成员方法时,该方法称为 类方法 或 静态方法;
(2)静态方法在声明中有 static,建议使用类名来调用,而不需要创建类的对象来调用,可以用类名.方法名()的形式访问由static修饰的类方法。
(3)类方法随着类的加载而加载,可以通过"类.静态方法"的方式进行调用;
(4)静态方法中,只能调用静态的方法或属性;
在static方法内部只能访问类的static修饰的属性或方法, 不能访问类的非static的结构。
非静态方法中,既可以调用非静态的方法或属性,也可以调用静态的方法或属性;
2、Demo
定义格式:
修饰符 static 返回值类型 方法名 (参数列表){
// 执行语句
}
Demo:在上面的 Student 类中定义一个静态方法
1 public static void showNum() {
2 System.out.println("num:" + numberOfStudent);
3 }
3、注意点
(1)静态方法可以直接访问静态变量和静态方法。(原因:因为在内存当中是【先】有的静态内容,【后】有的非静态内容。)
(2)静态方法不能直接访问普通成员变量或成员方法。反之,成员方法可以直接访问静态变量或静态方法。
(3) 静态方法中,不能使用 this,super 关键字。(原因:this代表当前对象,通过谁调用的方法,谁就是当前对象。)
(4)static修饰的方法不能被重写(static修饰的方法是随着类加载而加载,而重写是在编译时)
(5)静态方法只能访问静态成员,非静态方法即可以访问非静态成员也可以访问静态成员。
4、调用格式
被 static 修饰的成员可以并且建议通过 类名直接访问。虽然也可以通过对象名访问静态成员,原因即多个对象均属于一个类,共享使用同一个静态成员,但是不建议,会出现警告信息。
调用格式:
// 访问类变量
类名.类变量名;
// 调用静态方法
类名.静态方法名(参数);
四、static 修饰代码块
static 修饰代码块
小结:static 关键字,可以修饰变量、方法和代码块。在使用的过程中,其主要目的还是想在不创建对象的情况下,去调用方法。