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

一、

当编译器需要一个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 = 47
j = 39

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值