1、静态属性

1)什么是静态属性?

      - 被static修饰的属性就是静态属性。例如:static int i;

      - 语法结构:权限修饰符 static 数据类型 属性名;

为什么不推荐呢?这里先留个疑问。

2)怎么理解静态属性?

      - 我们见过类中不加static的属性,叫做实例属性。无论创建多少个对象,每个对象的实例属性互不影响。

      - 当实例属性被static修饰,就成为了静态属性,它被所有的实例所共享。也可以说,静态属性不属于实例对象。因为在任何一个实例中对静态属性的值进行改变,其他类中静态属性的值也随之发生变化。

推荐使用类名访问是为什么呢?我们把静态属性理解为类本身的属性,实例中不包含静态属性,静态属性可以被所有实例对象共享。

3)为什么要引入静态属性?

      - 各对象之间的数据有了沟通的渠道,实现了数据的共享。当我们在涉及到在对象间实现数据共享时就使用静态属性。

4)静态属性的特点?

      - 声明为static的属性也被称为类属性

      - 当创建一个对象时,并不产生static属性的拷贝

      - 该类的所有实例共享一个static属性

      - 在类加载时,只分配一块储存空间,所有的类的对象都可以对此空间进行操作

2、静态方法

1)什么是静态方法?

      - 被static修饰的方法叫做静态方法。

      - 语法结构:权限修饰符 static 返回值类型 方法名(形参列表){//...}

      - 调用方式:类名.方法名(实参列表)。通过实例对象也可以调用静态方法,只不过编译器自动把实例改为类名。通常情况下,使用实例对象访问静态属性和静态方法会得到一个编译警告。

普通成员方法也可以访问静态属性,那为什么还要用静态成员方法?留个疑问。

2)静态方法的使用?

public class Main{
    public static void main(String[] args){
        Person.setAge(20);
        System.out.println(Person.age);
    }
}
class Person{
    public static int age;
    
    public static void setAge(int Age){
        age = Age; //直接访问static类型的属性
    }
}

      - 在静态方法中,只能直接访问static类型的属性。

      - 在静态方法中,只能直接调用static类型的方法。

      - 在静态方法中,不能使用this和super。

      - 这些限制的原因都是因为static的出现使其脱离了实例。虽然脱离实例但是static是被实例共享的。就是说可以用类名或者对象访问。

3)private static

普通成员方法也可以访问静态属性,那为什么还要用静态成员方法?这是因为,为了更好的体现封装性,类中的属性设为私有的。假设我们使用普通方法访问静态属性,那么我们就不能用类名调用普通方法来访问静态属性。只能先创建对象,用实例调用普通方法,访问静态属性。举例如下:

public class Main{
    public static void main(String[] args){    	    	
        Person.setAge(20); //编译错误
        System.out.println(Person.getAge()); //编译错误

        Person p1 = new Person();
        p1.setAge(30);
        System.out.println(p1.getAge());          
    }
}
class Person{
    private static int age;
    
    public void setAge(int Age){ //普通成员方法
        age = Age; 
    }
    
    public int getAge(){ //普通成员方法
        return age;
    }
}

      - 要注意的是,private static是无法将属性私有化在一个实例中的,它仍能被所有实例共享。

3、静态代码块

1)什么是静态代码块?

      - 语法规则: 

static{
    //...
}

      - 功能:初始化static变量。

      - 特点:仅在该类加载时执行一次。

2)为什么要用静态代码块?

      - 静态属性的初始化可以在定义时进行,如static int a = 1; 如果初始化非常复杂时,就可以在静态代码块中进行属性的初始化。

3)在涉及继承时,先初始化父类的静态代码块,再初始化子类的静态代码块。

4)子类实例化对象时的执行顺序?

      - 父类的静态代码块

      - 子类的静态代码块

      - 父类的构造方法

      - 子类的构造方法

4、扩展

      - 非静态语法结构:

{
    //...
}

      - 类中代码执行顺序:1、静态属性和静态方法(按照定义顺序,在类加载时执行一次)2、非静态属性和非静态代码块(按照定义顺序,在类被实例化时执行)3、构造函数

5、静态类

      - 通常一个类不允许被声明为静态的,只有一个内部类才可以。

      - 声明为静态的内部类可以直接作为一个普通类来使用,而不用实例化一个外部类。

6、static final

      - static final修饰变量或成员方法,可以简单理解为全局变量。

      - 对于常量,一旦访问就不可修改,可以通过类名访问。

      - 对于方法,表示该方法不可覆盖,可以通过类名访问。

7、总结对于静态的理解

      - static表示“全局”或者“静态”的意思(static不是公有,是静态。public是公有。),用来修饰成员变量和成员方法,也可以形成静态static代码块,但是Java语言中没有全局变量的概念。

      - 被static修饰的成员变量和成员方法独立于该类的任何对象,它不依赖类特定的实例,被类的所有实例共享。

      - static 变量前可以有private修饰,表示这个变量可以在类的静态代码块中,或者类的其他静态成员方法中使用(当然也可以在非静态成员方法中使用),但是不能在其他类中通过类名来直接引用。

      - 用static修饰的代码块表示静态代码块,当Java虚拟机(JVM)加载类时,就会执行该代码块。