在定义一个类时,只是在描述某事物的特征和行为,并没有产生具体的数据。只有通过new关键字创建该类的实例对象时,才会开辟栈内存和堆内存,在堆内存中每个对象会有自己的属性。如果希望某些属性被所有对象共享,就必须将其声明为static属性。如果属性使用了static关键字进行修饰,则该属性可以直接用类名称进行调用。static可以修饰成员属性,也可以修饰成员方法以及代码块。
一、静态属性
用static关键词修饰的属性称为静态属性(也称为全局属性),静态属性可以直接使用类名直接访问,访问格式为:
类名.属性名
或
实例名对象.属性名
例如:
class Student6{
String name;
int age;
String sex = "female";
public Student6(String name,int age){
this.name = name;
this.age = age;
}
public void read(){
System.out.println("姓名:"+this.name+",年龄:"+this.age+",性别:"+this.sex);
}
}
public class usage_0f_static {
public static void main(String[] args){
Student6 stu1 = new Student6("张三",19);
Student6 stu2 = new Student6("李四",18);
Student6 stu3 = new Student6("王五",20);
stu1.read();
stu2.read();
stu3.read();
}
}
上述案例中,假如我们将三位同学的性别都写错了要进行修改,我们需要修改3个对象共三次,比较麻烦。为了解决这个问题,我们可以用static修饰sex属性,将其变成公共属性。这样,sex属性只分配了一块内存,被所有的对象所共享。
class Student6{
String name;
int age;
static String sex = "female";
public Student6(String name,int age){
this.name = name;
this.age = age;
}
public void read(){
System.out.println("姓名:"+this.name+",年龄:"+this.age+",性别:"+this.sex);
}
}
public class usage_0f_static {
public static void main(String[] args){
Student6 stu1 = new Student6("张三",19);
Student6 stu2 = new Student6("李四",18);
Student6 stu3 = new Student6("王五",20);
Student6.sex = "male"; //类名加属性名
stu1.read();
stu2.read();
stu3.read();
}
}
注意:
public class Student{
public void study(){
static int score = 99; //static不能修饰此局部变量
}
}
二、静态方法
与静态属性相同,静态方法也可以通过类名和对象访问,访问格式为:
类名.方法
或
实例名对象.方法
最常见的static方法就是main方法,程序在执行main方法时不需要创建对象,直接通过类名来访问。
class Student6{
private String name;
private int age;
private static String sex = "female";
public Student6(String name,int age){
this.name = name;
this.age = age;
}
public void read(){
System.out.println("姓名:"+this.name+",年龄:"+this.age+",性别:"+this.sex);
}
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 getSex(){
return sex;
}
public static void setSex(String sex){
Student6.sex = sex; //使用了static,这里不能用this.sex,而是要用”类名.属性名“来访问
}
}
public class usage_0f_static {
public static void main(String[] args){
Student6 stu1 = new Student6("张三",19);
Student6 stu2 = new Student6("李四",18);
Student6 stu3 = new Student6("王五",20);
stu1.setAge(20);
stu2.setName("小李");
Student6.setSex("male");
stu1.read();
stu2.read();
stu3.read();
}
}
上面案例演示如何调用静态方法。注意:静态方法只能访问静态成员,因为非静态成员需要先创建对象才能访问,即随着对象的创建,非静态成员才会被分配内存。而静态方法在被调用时可以不创建任何对象。
三、静态代码块
在Java类中,用static关键字修饰的代码块称为静态代码块。当类被加载时,静态代码块会被执行,但类只会加载一次,因此静态代码块只执行一次。
class Test1 extends Test2{ //Test2为父类,Test1为子类,extends为继承
static{
System.out.println("Test1的静态代码块");
}
public Test1(){
System.out.println("Test1的构造块");
}
}
public class usage_0f_static{
public static void main(String[] args) {
Test1 test1 = new Test1();
}
}
class Test2{
static{
System.out.println("Test2的静态代码块");
}
public Test2(){
System.out.println("Test2的构造块");
}
}
上述案例运行结果为
Test2的静态代码块
Test1的静态代码块
Test2的构造块
Test1的构造块
另外,代码的执行顺序为静态代码块、构造代码块、构造方法。静态代码块在类第一次加载使用时才会被加载,并且只会加载一次。