一、static概述
static是Java中的关键字,可以修饰变量、方法、代码块。被static修饰的变量、方法、代码块称为静态成员,存放于内存的方法区,并且伴随类的加载而加载,不单独属于类的某个对象。
二、static修饰成员变量
被static修饰的成员变量称为静态成员变量,是类的一个属性,其生命周期伴随类的一生。
例如:Student类的clase为静态成员变量
public class Student { private String name; private int age; public static String clase;//学生所属的班级 public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public static String getClase() { return clase; } public static void setClase(String clase) { Student.clase = clase; } public Student(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
在Main类对Student类做一些测试:
class Main{ public static void main(String[] args) { Student student = new Student(); System.out.println(student.clase); System.out.println(Student.clase); } }
运行结果:
null为String变量的默认值,通过上述例子我们可以看出:类和对象都能访问静态成员变量。
在含有静态成员变量的类的构造方法中,通常不含有静态成员变量。
对静态成员变量初始化下方式:
- 默认赋值:整型变量默认赋值为0,浮点型默认赋值为0.0,char型默认赋值为'\u0000',boolean型变量默认赋值为false,引用变量默认赋值为null。
- 直接赋值:在定义静态成员变量时直接赋值,例如:public static String clase="计算机202"。
- 利用提供的get()方法进行赋值。
- 通过代码块赋值。
三、static修饰成员方法
被static修饰的成员方法成为静态成员方法。
静态成员方法既可以通过类,也可以通过对象,但更推荐前者。
静态成员方法中不能调用非静态的成员方法和属性,但是普通成员方法是可以调用静态成员方法的。对于静态成员变量的get和set方法推荐使用静态成员方法,否则想要获取静态成员变量时,必须先实例化一个对象,这样使静态成员变量失去了意义。
class Main{ public static void main(String[] args) { Student student = new Student("李明",12); student.printClase(); } }
运行结果:
四、static修饰代码块
代码块:被{}修饰的一段代码,通常可以分为普通代码块,构造代码块,静态代码块,同步代码块(用于多线程,此处不作解释)。
普通代码块:定义在方法内部的代码块。
例如在Student类中增加一个test方法:
public void test(){ System.out.println("下面是普通代码块"); { System.out.println("这是普通代码块"); } }
class Main{ public static void main(String[] args) { Student student = new Student("李明",12); student.test(); } }
运行结果:
所以普通代码块在方法内部按顺序执行,通常是用于限定一个变量的作用范围 。
构造代码块: 定义在类中的代码块,不加任何修饰符。
实例代码块只有在创建对象时才会执行。
例如在Student类中定义一个构造代码块如下:
{ this.name="张三"; this.age=10; System.out.println("这是构造代码块"); }
class Main{ public static void main(String[] args) { Student student = new Student(); System.out.println(student); } }
运行结果:
在实例化对象时,并没有初始化,但是会自动调用构造代码块,对对象的相关成员变量赋值。
当时如果将成员变量定义在构造代码块之后,并直接为赋值时,会覆盖构造代码块的赋值。
例如:
{ this.name="张三"; this.age=10; System.out.println("这是构造代码块"); } private int age=25;
运行结果为:
class Main{ public static void main(String[] args) { Student student = new Student("刘强",15); System.out.println(student); } }
运行结果:
当实例化对象时进行了初始化,还是会自动调用构造代码块,但构造有参方法对成员赋值会覆盖构造代码块的赋值。
静态代码块:使用static定义的代码块称为静态代码块。一般用于初始化静态成员变量。
例如在Student类中定义一个静态代码块:
static{ clase="计算机203"; System.out.println("这是静态代码块"); }
class Main{ public static void main(String[] args) { Student student = new Student(); System.out.println(Student.getClase()); } }
运行结果:
静态代码块要先于构造代码块执行。
class Main{ public static void main(String[] args) { Student student1 = new Student(); System.out.println("==================="); Student student2 = new Student(); System.out.println("==================="); Student student3 = new Student(); } }
运行结果:
不管生成几个对象,静态代码块只会执行一次。