java学习笔记13(final static)

  final  :意味最终,不可变,,是一个修饰词

有时候一个类的功能被开发好了,不想让子类重写,修改,就会用final

final 修饰类:

不可以被继承,但可以继承其他类

public final class Fu {
    public void show(){
        System.out.println("最终类的方法");
    }
    //这个类不能被继承
    //使用方法不变
}

public class Test {
    public static void main(String[] args) {
        Fu f = new Fu();
        f.show();
    }
}

final 修饰方法不能被子类重写

public class Fu {
    public final void show(){
        System.out.println("父类的最终方法");
    }
    public void function(){
        System.out.println("父类的一般方法");
    }
}
public class Zi extends Fu {
    public void function(){
        System.out.println("子类重写父类的一般方法");
    }
    //不可以重写父类的show方法
}
public class Test {
    public static void main(String[] args) {
        Zi z = new Zi();
        //方法的使用方式没有改变
        z.function();
        z.show();
    }
}

final修饰的变量称为常量,只能被赋值一次,一次赋值终身不变

如果final修饰引用数据类型,那么保存变量的内存地址将终身不变

final修饰成员变量

成员变量保存在堆内存中,是有默认的值的,所以final修饰的成员变量必须要赋值

由于成员变量的赋值方法有两种:直接赋值和构造方法赋值所以final修饰的成员变量可以选一种赋值

但是必须保证只赋值一次

public class Person {
    //直接赋值(实际中建议这样方式):
    //final int age = 18;
    //构造方法赋值:
    final int age;
    public Person(int age){
        this.age = age;
    }
}

static:

意义举例:

一个学校里有一群学生对象,他们都有不同的姓名和年龄,但是他们的学校名都是相同的,

创建学生对象的时候,成员变量中的学校名在每次新建对象的时候都会存入堆内存,但是每次存的数据都是相同的,造成了内存的浪费

于是想到,能否将学校名提出来,放到某个地方,让多个对象共享,节省内存

于是,出现了static关键字:

静态多了一种调用方式

被静态修饰的成员,可以被类的名字直接调用

public class Person {
    String name;
    static String className;
}
public class Test {
    public static void main(String[] args) {
        Person p1 = new Person();
        Person p2 = new Person();
        p1.name = "张三";
        p2.name = "李四";
        p1.className = "一班";
        //共享数据的特性:一处改,其他对象跟着改
        System.out.println(p2.className);
        System.out.println(Person.className);
    }
}
//输出:一班

静态的注意事项:

静态不能调用非静态:

原因:声明周期

静态优先于非静态存在于内存在,无法调用不存在的

比如古人无法访问现代人

非静态可以调用静态

比如现代人可以访问古人(可能有点不恰当...理解就行)

静态不能用this,super方法,

同样,静态在创建对象前就存在,不允许访问不存在的

而在实际中,通常静态对静态,非静态对非静态

public class Student {
    private String name;
    private static int age;
    public static void function(){
        //System.out.println(name);
        //这里的静态方法不能调用非静态
    }
    public void show(){
        System.out.println(age);
        //非静态可以调用静态
    }
}

静态修饰应用场景:

本身是一个成员修饰符,可以修饰成员变量,可以修饰成员方法

多个事物之间是否存在共性数据?这里就可以将这个共性数据定义成静态

只要方法没有调用过非静态成员,则将其定义为静态

对象中的静态调用:

这里是之前多态中的一个难点:

public class Fu {
    static int i = 1;
    public static void show(){
        System.out.println("父类的静态方法");
    }
}
public class Zi extends Fu {
    static int i = 2;
    public static void show(){
        System.out.println("子类的静态方法");
    }
}
public class Test {
    public static void main(String[] args) {
        Fu f = new Zi();
        System.out.println(f.i);
        f.show();
    }
}
/*输出:
父类的静态方法
*/

/*
 多态中,编译看等号左边的,父类有编译成功,父类没有,编译失败
 运行看等右边的,
 如果是静态方法,运行的是父类中的静态方法
 如果是非静态方法,运行的是子类重写的非静态方法
 成员变量:
 无论静态非静态,编译运行都是父类的
 
 根本原因:静态属于类,不输入对象
 多态性是讨论对象的性质,而静态和对象无关,
*/

最后,

在开发中,有时候需要定义静态常量,并且常量名要求全大写,空格用_代替

固定格式:public static final String THIS_NAME = "XXXX"

原文地址:https://www.cnblogs.com/bxl-1016/p/10720194.html