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)加载类时,就会执行该代码块。