Fork me on GitHub

final关键字,类初始化构造器调用顺序

final

含义:不可改变的。(不可重写)

特点:

  1。一个永不改变的编译时常量。

  2.一个在运行时初始化就不会改变的值

 

final数据:要求:定义常量时必须赋值。

如果是空的final对象,则会要求在构造器中初始化。

示例:

public class BlankFinal {
    private final int i = 0; // Initialized final
    private final int j; // Blank final
    private final Poppet p; // Blank final reference
    // Blank finals MUST be initialized in constructor
    public BlankFinal() {
        j = 1; // Initialize blank final
        p = new Poppet(1); // Init blank final reference
    }

    public BlankFinal(int x) {
        j = x; // Initialize blank final
        p = new Poppet(x); // Init blank final reference
    }
}

final static :static 强调只有一个,final 说明是一个常量。

final 参数:不能指定

示例:

public class FinalArguments {
    void with(final Gizmo g) {
        //-g = new Gizmo(); // Illegal -- g is final
    }

    void without(Gizmo g) {
        g = new Gizmo(); // OK -- g is not final
        g.spin();
    }

    //void f(final int i) { i++; } // Can't change
    // You can only read from a final primitive
    int g(final int i) {
        return i + 1;
    }

    public static void main(String[] args) {
        FinalArguments bf = new FinalArguments();
        bf.without(null);
        bf.with(null);
    }

final和private:含义相似,private方法不能访问因此含有隐式的final,当我们试图重写private方法时,由于重写的方法要求时public或protected,private方法不能访问,所以其实只是在创建新的方法。

final类:不能被继承。

final建议:别随便用,用时要考虑清楚,因为有时我们不能准确推断该方法是否真的不会被重写。

 

类初始化构造器调用顺序

注意:类中private关键词字标注的默认含有隐式的static

调用顺序:

0.在所有事发生前,分配给对象的存储空间会被初始化为二进制 0。

1.从基类的static方法开始,到类本身的static方法

2.从继承的基类开始调用构造方法,直到调用完最底层的派生类。

3.按声明顺序初始化成员。

4.调用类自身构造器方法

示例一:

// reuse/Beetle.java
// The full process of initialization
class Insect {
    private int i = 9;
    protected int j;

    Insect() {
        System.out.println("i = " + i + ", j = " + j);
        j = 39;
    }

    private static int x1 = printInit("static Insect.x1 initialized");

    static int printInit(String s) {
        System.out.println(s);
        return 47;
    }
}

public class Beetle extends Insect {
    private int k = printInit("Beetle.k.initialized");

    public Beetle() {
        System.out.println("k = " + k);
        System.out.println("j = " + j);
    }

    private static int x2 = printInit("static Beetle.x2 initialized");

    public static void main(String[] args) {
        System.out.println("Beetle constructor");
        Beetle b = new Beetle();
    }
}

结果:

static Insect.x1 initialized
static Beetle.x2 initialized
Beetle constructor
i = 9, j = 0
Beetle.k initialized
k = 47
j = 39

示例二:

// polymorphism/PolyConstructors.java
// Constructors and polymorphism
// don't produce what you might expect
class Glyph {
    void draw() {
        System.out.println("Glyph.draw()");
    }

    Glyph() {
        System.out.println("Glyph() before draw()");
        draw();
        System.out.println("Glyph() after draw()");
    }
}

class RoundGlyph extends Glyph {
    private int radius = 1;

    RoundGlyph(int r) {
        radius = r;
        System.out.println("RoundGlyph.RoundGlyph(), radius = " + radius);
    }

    @Override
    void draw() {
        System.out.println("RoundGlyph.draw(), radius = " + radius);
    }
}

public class PolyConstructors {
    public static void main(String[] args) {
        new RoundGlyph(5);
    }
}

结果:

Glyph() before draw()
RoundGlyph.draw(), radius = 0
Glyph() after draw()
RoundGlyph.RoundGlyph(), radius = 5

建议不要在构造器中调用方法!

posted @ 2020-12-20 11:05  卡卡北  阅读(244)  评论(0)    收藏  举报