zoukankan      html  css  js  c++  java
  • java笔记之final和static关键字

    前言

    类的加载顺序为:
    (1)初始化变量。对于静态变量肯定要首先进行初始化,因为后面的方法可能会使用这个变量,或者构造函数中也可能用到。而对于非静态变量而言,由于匿名块内、非静态方法和构造函数都可以进行操作(不仅仅是初始化),所以要提前进行加载和赋默认值。
    (2)初始化静态代码块,多个静态代码块按顺序加载,这里需要注意:在这个顺序是类内书写的顺序,也是类加载的顺序.由于静态代码块可能会负责变量的初始化,或者是对象等的初始化,这样在构造函数或者方法中就变得可用了。
    (3)匿名代码块,这个要后初始化于静态代码块,因为其依然属于实例对象,而不属于类。在这里可以对非静态成员变量进行初始化工作。
    (4)构造函数 这里需要解释一下,为什么初始化子类必先初始化父类,由于子类可能会继承父类的属性或方法,所以肯定要先初始化父类了,而初始化父类则必须要调用父类的构造函数。
    至于方法不用考虑,因为方法不用初始化.

    1.final 

    1)修饰类 该类不能被继承(在实际开发过程中尽量少使用final修饰类,因为系统要具备可扩展性和可维护性

    2)使用final修饰方法,方法不能被重写

    3)final 修饰属性:被final修饰的属性必须初始化,初始化之后值不能改变(属性为简单类型时是值不变;属性为引用类型时是地址不变,其指向的对象的属性可以改变)

    4)final修饰变量:

    修饰方法的形参,该参数只能读不能写

    修饰局部变量,一般在内部类使用(可以先定义,再赋值一次)

    5)final定义常量:

    public  static final  类型 变量名 =值

    2.static关键字

    1)static 修饰属性

    被static修饰的属性,是属于类级别的属性。他被该类所产生的对象所共有

    1))静态属性的访问方式

    类的外部:类名。属性名

    类的内部:属性名即可,等价于类名。属性名

    注:静态属性可以被非静态的方法和静态的方法中直接访问

    2)static修饰方法:

    被static修饰的方法,是属于类级别的方法。他是该类所产生的所有的对象所共享的方法

    1))静态方法的访问方式:

    类名。方法名(参数),适用于类的内部和类的外部

    方法名(参数),适用于类的内部

    注:

    a.静态方法调用属性,只能直接调用静态属性,非静态的属性只能通过对象引用才能调用

    b.静态方法调用方法,只能直接调用静态方法,非静态的方法只能通过对象引用才能调用

    c.在静态方法中,不能使用this,super调用属性和方法(构造器不能使用static修饰);原因是静态的方法先于非静态的属性和非静态的方法加载;具体参考下面的代码分析。

    d.非静态的方法可直接调用讲台的方法和静态的属性

    3)static静态块:

    在类体中:

    static {

    代码

    }

    注:static块只能在类体中定义,不能在方法中定义

    1))执行方式:

    static 块是在类加载时,该语句就会被执行;且此语句只能被执行一次(因为:类采用的懒加载的方式,也就是说,如果内存中的方法区已存在该类的代码,那么就不会加载第二次;如果内存中不存在代码就会被加载,同时静态块也会被执行)

    注:java命令找到带有mian方法的类,通过类加载器该类加载到方法区

    静态域:存放静态属性、静态方法和静态块。

    2))应用场景:

    加载配置文件,也可使用于只需加载一次的资源(如:读取文件,加载数据库驱动)

    3))static修饰类(内部类)

    语法:

    static class 类名{

    类体

    }

    1))特性:

    1)))在静态内部类中访问外部类的成员,该成员必须是static的;可以使用外部类的对象引用来访问外部类的非静态成员

    2)))静态内部类的实例化方式:

    外部类类名。内部类类名 变量名 =new 外部类类名。内部类类名(参数列表);

    3)))静态内部类可被四大访问控制修饰符所修饰

    4)))静态内部类可直接调用外部类的静态方法;也可以使用外部了引用来调用非静态的方法

    5)))外部类访问静态内部类的静态方法:

    外部类类名。方法名

    外部类访问内部类的FAI静态方法:内部类引用。方法名;



    4)代码示例分析:

    Joo.run(参数类表);

    分析:

    1))检查Joo是否存在代码区

    2))若存在代码区,就不加载Joo代码。若不存在,就将Joo的代码加载到方法区中。

    将被static修饰的属性、方法和静态块放置到静态域中,将普通方法放置在普通方法区中。

    3))当Joo的代码加载完毕之后,立即执行static块;

    4))通过Joo的地址在静态域中找到run方法,并且执行run方法。

    Joo J=new Joo(参数类表);

    1))检查J00在代码区是否存在

    2))若存在,就直接在堆区中开辟空间,并将非静态的属性以及非静态的方法引用存在堆区中。

    3))在栈区开辟空间,记录堆区对象地址。

    Joo.print(参数类表);

    1))通过栈区引用的地址,找到堆区中的方法的地址,然后再在方法区找到方法,并执行。


    总结

    创建一个不可变类(不可变类是指当创建了这个类的实例后,就不允许修改它的属性值)需要如下条件:
    1. 对于一般成员都是private,还可以使用public static final 来定义一个全局的常量。
    2. 不提供对成员的修改方法,例如:setXXX()
    3. 确保所有的方法不会被重载。手段有两种:使用final Class(强不可变类),或者将所有的类方法加上final关键字(弱不可变类)。
    4. 如果某一个类成员不是原始变量(primitive)或者不可变类,必须通过在成员初始化或者get方法时通过深度clone方法,来确保类的不可变。

    博客:https://kunnan.blog.csdn.net
  • 相关阅读:
    pointcut通配符
    Java设计模式-建造者(Builder)模式
    mybatis 初步使用(IDEA的Maven项目, 超详细)
    静态代理和动态代理
    Java 多线程(五)之 synchronized 的使用
    Java 多线程(四)之守护线程(Daemon)
    HashMap 源码解析(一)之使用、构造以及计算容量
    Java 多线程(三)之线程状态及其验证
    Java 多线程(二)之 Thread 优先级
    Java 多线程之 Thread 类 和 Runnable 接口初步使用
  • 原文地址:https://www.cnblogs.com/zhang_kun_nan/p/3636485.html
Copyright © 2011-2022 走看看