Java - static、final、this、super关键字总结

in TCEHJava with 0 comment

static

用途:方便在没有创建对象的情况下来进行调用(方法/变量)。

static 关键字主要有以下五种使用场景:

静态导包(很少用)

  格式为:import static这两个关键字连用可以指定导入某个类中的指定静态资源,并且不需要使用类名调用类中静态成员,可以直接使用类中静态成员变量和成员方法。

import static com.back.entity.User.*;//这样便可以直接使用User类的静态资源,而无需通过类名类进行调用。

static内部类(static修饰类的话只能修饰内部类):

  静态内部类与非静态内部类之间存在一个最大的区别: 非静态内部类在编译完成之后会隐含地保存着一个引用,该引用是指向创建它的外围内,但是静态内部类却没有。没有这个引用就意味着:1. 它的创建是不需要依赖外围类的创建。2. 它不能使用任何外围类的非static成员变量和方法。

static方法

  static方法一般称作静态方法,由于静态方法不依赖于任何对象就可以进行访问,也就是被所有对象共享,因此对于静态方法来说,是没有this的,因为它不依附于任何对象,既然都没有对象,就谈不上this了。并且由于这个特性,在静态方法中不能访问类的非静态成员变量和非静态成员方法,因为非静态成员方法/变量都是必须依赖具体的对象才能够被调用。

注意:

a.调用格式:类名.静态变量名 类名.静态方法名()

b.虽然在静态方法中不能访问非静态成员方法和非静态成员变量,但是在非静态成员方法中是可以访问静态成员方法/变量的。

c.构造方法是静态方法吗?答案:不是。参考大神解答:https://blog.csdn.net/qq_17864929/article/details/48006835

d.静态方法/变量虽然独立于对象,但是所有的静态方法和静态变量都可以通过对象访问

static变量

  static变量也称作静态变量,静态变量和非静态变量的区别是:静态变量被所有的对象所共享,在内存中只有一个副本,它当且仅当在类初次加载时会被初始化。而非静态变量是对象所拥有的,在创建对象的时候被初始化,存在多个副本,各个对象拥有的副本互不影响。静态变量 存放在 Java 内存区域的方法区。

a.static成员变量的初始化顺序按照定义的顺序进行初始化。
b.static不允许用来修饰局部变量

static代码块

  static关键字还有一个比较关键的作用就是 用来形成静态代码块以优化程序性能。static块可以置于类中的任何地方,类中可以有多个static块。在类初次被加载的时候,会按照static块的顺序来执行每个static块,并且只会执行一次。

咱们来看一段有意思的代码

package com.back.web;

public class StaticTest extends Father {
    MemberVariables person = new MemberVariables();
    static {
        System.out.println("子类静态代码块");
    }

    {
        System.out.println("子类非静态代码块");
    }

    public StaticTest() {
        System.out.println("子类构造方法");
    }

    public static void main(String[] args) {
        new StaticTest();
    }
}

class Father {
    public Father() {
        System.out.println("父类无参数构造方法");
    }

    static {
        System.out.println("父类静态代码块");
    }
    {
        System.out.println("父类非静态代码块");
    }

    public Father(String str) {
        System.out.println("父类构造方法:" + str);
    }
}

class MemberVariables extends Father {
    Father person = new Father("成员变量");
    static {
        System.out.println("成员变量静态代码块");
    }
    {
        System.out.println("成员变量非静态代码块");
    }

    public MemberVariables() {
        System.out.println("成员变量构造方法");
    }
}

上述代码的输出结果为:

父类静态代码块

子类静态代码块

父类非静态代码块

父类无参数构造方法

子类成员变量静态代码块 //其实在这步之前,会进入Father,但是Father中的static已经初始化过了,因此会回到MemberVariables。

父类非静态代码块

父类无参数构造方法

父类非静态代码块

父类构造方法:成员变量

子类成员变量非静态代码块

子类成员变量构造方法

子类非静态代码块

子类构造方法

总结执行顺序:

1、单类:静态代码块->非静态代码块->构造方法

2、单类有成员变量成员变量跟非静态代码块按顺序执行。也就是如果成员变量优先则:
静态代码块 -> 成员变量静态代码块 -> 成员变量非静态代码块 -> 成员变量构造方法 -> 非静态代码块 -> 构造方法

3、有父类:父类静态代码块 -> 子类静态代码块 -> 父类非静态代码块 -> 父类无参数构造方法 -> 子类非静态代码块 -> 子类构造方法

4、有父类且父类有成员变量(成员变量优先于非静态代码块):父类静态代码块 -> 子类静态代码块
-> 父类成员变量静态代码块 -> 父类成员变量非静态代码块 -> 父类成员变量构造方法 -> 父类非静态代码块
-> 父类无参数构造方法 -> 子类非静态代码块 -> 子类构造方法

5、有父类且子类有成员变量(成员变量优先于非静态代码块):父类静态代码块 -> 子类静态代码块 
-> 父类非静态代码块 -> 父类无参构造方法 -> 子类成员变量静态代码块 -> 子类成员变量非静态代码块
-> 子类成员变量构造方法 -> 子类非静态代码块 -> 子类构造方法

记忆点:
1、类加载,会执行 静态代码块。类实例化会执行 初始化成员变量&非静态代码块&构造方法等
2、要生成子类对象必须先生成父类对象。
3、成员变量|非静态代码块 按顺序执行。
4、基于1的原则。如果有main方法,先执行完当前类的静态代码块,再执行main方法,

final

final关键字主要用在三个地方:类、方法、成员变量。

修饰类

  当用final去修饰一个类的时候,表示这个类不能被继承

注意:

a. 被final修饰的类,final类中的成员变量可以根据自己的实际需要设计为final。

b. final类中的成员方法都会被隐式的指定为final方法。

说明:一般来说工具类我们往往都会设计成为一个fianl类。在JDK中,被设计为final类的有String、System等。

修饰方法

  被final修饰的方法不能被重写

注意:

a. 一个类的private方法会隐式的被指定为final方法

b. 如果父类中有final修饰的方法,那么子类不能去重写。

修饰成员变量

a. 被final修饰的变量即为常量,必须要赋初始值,而且是只能初始化一次。

b. 被fianl修饰的成员变量赋值,有两种方式:1、直接赋值 2、全部在构造方法中赋初值

c. 如果修饰的成员变量是基本类型,则表示这个变量的值不能改变。

d. 如果修饰的成员变量是一个引用类型,则是说这个引用的地址的值不能修改,但是这个引用所指向的对象里面的内容还是可以改变的

this

this关键字用于引用类的当前实例。我们编程中最常见的实体类:

public class User {
    private int id;
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;//因为形参名称与成员变量名称相同,因此需要用this来调用成员变量
    }
}

super

super关键字用于从子类访问父类的变量和方法。

    @Override
    public String toString() {
        // TODO Auto-generated method stub
        return super.toString();//此处便是调用父类的toString()方法
    }
Comments are closed.