理解Java中的static、final关键字

一、static关键字

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

static关键字属于类,而不是类的实例。也就是说,它不依赖类特定的实例,可以被类的所有实例共享。

static关键字的作用:方便在没有创建对象的情况下来进行调用(方法/变量)

1. static变量

按照是否静态的,对类成员变量进行分类,可分两种:

将一个变量声明为static,那么这个变量称为静态变量;而没有被static修饰的变量,叫实例变量。

静态变量可以直接通过类名来访问,访问语法为:

类名.静态变量名

实例变量需要创建一个实例,然后才能进行访问

public class Person {
  public int age;  //实例变量
}
public static void main(String[] args) {
  Person person = new Person();  //创建一个实例
  person.age;  //访问实例变量
}

2. static方法

如果在任何方法上应用static关键字,此方法称为静态方法。

  • 静态方法属于类,而不属于类的对象。

  • 可以直接调用静态方法,而无需创建类的实例。

  • 访问语法为:

类名.静态方法名(参数列表...)

static方法注意点:

  1. 静态方法可以直接通过类名调用,任何的实例也都可以调用,因此静态方法中不能用this和super关键字
  2. static方法不能直接访问所属类的实例变量和实例方法,只能访问所属类的静态成员变量和成员方法。因为实例成员与特定的对象关联!

3. static代码块

static代码块也叫静态代码块,是在类中独立于类成员的static语句块,静态代码块只能写在类中方法外,不能写在任何的方法体内,可以有多个,位置可以随便放。JVM加载类时会直接执行这些静态的代码块,优先于各种代码块和构造方法的加载。如果static代码块有多个,JVM将按照它们在类中出现的先后顺序依次执行它们,每个代码块只会被执行一次

静态代码块是严格按照父类静态代码块->子类静态代码块的顺序加载的,且只加载一次。

Java中的静态块主要的作用:

  • 一般情况下,有些代码需要在项目启动的时候就执行,这时候就需要静态代码块,比如一个项目启动需要加载配置文件,或初始化内容等

  • 用于初始化静态数据成员。

  • 它在类加载时在main方法之前执行。

    静态代码块示例

    执行结果

各代码块和构造器的执行顺序

静态代码块 > 匿名代码块 > 构造方法 > 普通代码块

执行结果:

4. 静态导入包

当我们想调用编译器自带的类中的方法时,我们可以导入其所在的包,比如调用Math类中的random()方法时,可以导入包从而直接调用random()方法

静态与非静态的区别

  1. 调用方式不同

调用静态方法:在主类里使用:类名.方法名

调用非静态方法:通过实例化这个类:new 调用的方法中的类名.方法名

  1. 在当前类中,可以直接访问静态方法,可通过类名.方法名()或者直接方法名(),

    例如,在Student类中

  2. 非静态方法可以调用静态方法,而静态方法不能调用非静态方法

  3. 对于静态属性,子类可以继承父类的静态属性,但是当父子类出现相同的非静态属性时,父类的非静态属性会被隐藏。

    对于静态方法,子类可以继承父类的静态方法,但是不能重写静态方法,同名时会隐藏父类的。

  4. 在内存中存放的位置不同:所有static修饰的属性和方法都存放在内存的方法区里,而非静态的都存在堆内存中

  5. 出现的时机不同:静态属性和方法在没创建对象之前就存在,而非静态的属性和方法需要在创建对象才存在

  6. 生命周期不一样:静态在类消失后被销毁,非静态在对象销毁后销毁

二、final关键字

Java关键字final有“这是无法改变的”或者“终态的”含义,它可以修饰非抽象类、非抽象类成员方法和变量。

final: 不可改变。可以用于修饰类、方法和变量。

  • 类:被修饰的类,不能被继承,没有子类
  • 方法:被修饰的方法,不能被重写。
  • 变量:被修饰的变量,不能被重新赋值。

修饰类

语法格式:

final class 类名 {
}

当用final修饰一个类时,表明这个类不能被继承。也就是说,如果一个类你永远不会让他被继承,就可以用final进行修饰。final类中的成员变量可以根据需要设为final,但是要注意final类中的所有成员方法都会被隐式地指定为final方法。

比如常用的String类就是最终类。

注意:在使用final修饰类的时候,要注意谨慎选择,除非这个类真的在以后不会用来继承或者出于安全的考虑,尽量不要将类设计为final类。

修饰方法

语法格式:

修饰符 final 返回值类型 方法名(参数列表){
    //方法体
}

注意:

  1. 对于类、方法来说,abstract关键字和final关键字不能同时使用,因为矛盾。有抽象方法的abstract类被继承时,其中的方法必须被子类Override,而final不能被Override。

  2. 类的private方法会隐式地被指定为final方法。

使用final方法的原因有二:

第一、把方法锁定,防止任何继承类修改它的意义和实现。
第二、高效。编译器在遇到调用final方法时候会转入内嵌机制,大大提高执行效率。

final方法的好处:

  1. 提高了性能,JVM在常量池中会缓存final变量
  2. final变量在多线程中并发安全,无需额外的同步开销
  3. final方法是静态编译的,提高了调用速度
  4. **final类创建的对象是只可读的,在多线程可以安全共享

修饰变量

对于一个final变量,如果是基本类型的变量,则其数值一旦在初始化之后便不能更改;如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象。

基本类型

基本类型的局部变量,被final修饰后,只能赋值一次,不能再更改

引用类型

引用类型的局部变量,被final修饰后,只能指向一个对象,地址不能再更改。但是不影响对象内部的成员变量值的修改

  1. 类中的成员变量--类常量必须在声明时初始化

  1. 构造方法--final成员常量可以在构造函数初始化。
public class Person {
    final String name;

    public Person(String name) {
        this.name = name;
    }

  1. final参数

当函数参数为final类型时,你可以读取使用该参数,但是无法改变该参数的值。

public class Test4 {
  public static void main(String[] args) {
    new Test4().f1(2);
        }     
  
	public void f1(final int i) {
    //i++;    //i是final类型的,值不允许改变的.
    System.out.print(i);
    }
}

final关键字小结

  1. final成员变量必须在声明的时候初始化或者在构造器中初始化,否则就会报编译错误。final变量一旦被初始化后不能再次赋值。

  2. 局部变量必须在声明时赋值。 因为没有初始化的过程

  3. 在匿名类中所有变量都必须是final变量。

  4. final方法不能被重写, final类不能被继承

  5. 接口中声明的所有变量本身是final的。类似于匿名类

  6. final和abstract这两个关键字是反相关的,final类就不可能是abstract的。

  7. 将类、方法、变量声明为final能够提高性能,这样JVM就有机会进行估计,然后优化

三、static和final一块用表示什么

static final用来修饰成员变量和成员方法,可简单理解为“全局常量”!

连用的时候表示既要它是静态的,也要求它的值不能再被修改。

当一个常数或字符串我们需要在程序里反复反复使用的时候,我们就可以把它定义为static final,这样内存就不用重复的申请和释放空间。

被Static final修饰意义分别如下:

1、成员变量:属于类的变量且只能赋值一次,一旦给值就不可修改。

2、方法:属于类的方法且不可以被重写。

3、内部类:属于外部类,且不能被继承



此学习资料参考于:

https://www.jianshu.com/p/067b6c89875a
https://www.yiibai.com/java/static-keyword-in-java.html
https://blog.51cto.com/lavasoft/18771
https://cloud.tencent.com/developer/article/1921927)

posted @ 2022-04-21 23:42  ·追·  阅读(224)  评论(0)    收藏  举报
/*鼠标跟随效果*/ //返回顶部 returnTop