Thinking in java 读书笔记(四、toString,class的初始化顺序)

来源:互联网 发布:spring mvc nginx配置 编辑:程序博客网 时间:2024/06/06 00:16

一、

当编译器需要一个String,而只有对象的时候,自动调用toString方法
public class Test {    public String toString(){        return "caonima";    }    public static void main(String[] args) {        Test test = new Test();        System.out.println( test);    }}
结果为caonima;

二、

    如果父类没有无参构造器,子类的构造器必须使用super显式调用父类的带参构造器。    子类的构造器类型必须是小于等于父类的构造器形式,就是说如果父类没有无参构造器,则子类也不能有无参构造器,如果父类的构造器有N个,则子类的构造器形式可以是<=N个,且与父类必须一一对应。例子如下
class Game{    Game(int i){        System.out.println("Game Constructor");    }    Game(float c){        System.out.println("float");    }}class BoardGame extends Game{    BoardGame(int i) {        super(i);    }}这里子类可以只有带int参数的构造器,也可以多一个带float参数的构造器,但是不能有无参构造器,因为父类没有。

三、

    惊了,居然这么快就到代理了    惊了,原来之前写的Service和DAO层的关系就是代理关系了。    就是基类作为代理类的参数,而代理类提供和基类同名同参的方法,但是方法的实现选择直接调用基类的方法。简易代理如下:
public class SpaceshipDelegariton{    private String name;    private SpaceShipControls spaceShipControls = new SpaceShipControls();    public SpaceshipDelegariton(String name){        this.name = name;    }    public void up(int velocity){        spaceShipControls.up(velocity);    }}class SpaceShipControls{    void up(int velocity){}}

四、

final修饰的基本数据是不可变的,但是如果用于修饰对象参数,则该对象的引用不可变,但是内容可变
public class FinalData{    private static Random random = new Random(47);    private String id;    private final int i4 = random.nextInt(20);    static final int INT5_5 = random.nextInt(20);    private final Value v2 = new Value(22);    private final int[] a = {1,2,3,4,5,6,};    public String toString(){        return id+": "+"i4 = " + i4 + ", INT_5 = "+INT5_5;    }    public FinalData(String id){        this.id = id;    }    public static void main(String[] args) {        FinalData finalData = new FinalData("fd1");        //finalData.valueOne++; 语句报错,因为final无法改变的        finalData.v2.i++;//是可以的,只要不指定为其他对象即可,对象的自身数据可以改变        //finalData.v2 = new Value(22); 语句错误,因为重新指定了对象        for (int i=0;i<finalData.a.length;i++){            finalData.a[i]++;//可行,只要finalData.a不重新指定一个数组就可以        }        System.out.println(finalData);        FinalData finalData1 = new FinalData("fd2");        System.out.println(finalData1);    }}class Value{    int i;    public Value(int i){        this.i = i;    }}//这里还有一点要注意,static final 和final :static final修饰的数据一旦被创建,则作为静态数据一直存储一直不可变,而单纯的final则是每个对象创建的时候赋予一次,而不一定是一直不可变。//这里还有,就是如果一个class是final的则该class不可以被继承所有的包装类还有String都是final的。注意这些包装类的引用都是值传递

五、

继承和初始化,首先初始化父类的static,然后初始化子类的static,然后运行父类非static数据,然后父类构造器,然后子类的非static,然后子类构造器代码如下
public class Shit extends Insect {    private int k = printInit("子类的实例数据");    private static int x2 = printInit("子类的静态数据");    static {        System.out.println("子类的静态初始化");    }    {        System.out.println("子类的实例代码块");    }    public Shit(){        System.out.println("子类的构造器");        System.out.println("k = "+k);        System.out.println("j = "+j);    }    public static void main(String[] args) {        System.out.println("子类的静态方法d");        Shit m  = new Shit();    }}class Insect{    private int i = 9;    protected int j;    protected int caonima = printInit("父类的实例数据");    private static int x1 = printInit("父类的静态数据") ;    static {        System.out.println("父类的静态代码块");    }    {        System.out.println("父类的实例代码块");    }    Insect(){        System.out.println("父类的构造器");        System.out.println("i = "+i+", j = "+j);        j=39;    }    static int printInit(String s){        System.out.println(s);        return 47;    }}结果如下父类的静态数据父类的静态代码块子类的静态数据子类的静态初始化子类的静态方法d父类的实例数据父类的实例代码块父类的构造器i = 9, j = 0子类的实例数据子类的实例代码块子类的构造器k = 47j = 39
原创粉丝点击