Thinking in Java习题心得

[在构造函数中调用构造函数]

class Foo
{
   
public Foo()
    {
       
this("Default");
    }

    public Foo(String s)
    {
        System.out.println(s);
    }
}

public class Main
{

    public static void main(String[] args)
    {
        Foo f =
new Foo();
        Foo g =
new Foo("Param");
    }
}

 

[该死的gc]

在Java中垃圾收集是不能被强迫立即执行的。调用System.gc()或Runtime.gc()静态方法不能保证垃圾收集器的立即执行,因为,也许存在着更高优先级的线程。

[两种初始化的区别]

class T
{
    String s0 = "good", s1;

    public T()
    {
        s1 = "morning";
    }

    public String toString()
    {
        return s0 + " " + s1;
    }
}

public class Main
{
    public static void main(String[] args)
    {
        T t = new T();
        System.out.println(t);
    }
}

 

s0和s1均被初始化了,但是它们的区别是什么?那就是:s0首先就被初始化为"good",而s1先被初始化为null,然后再被赋值为"morning"。

[static型初始化的两个注意]

形如

class Cups
{
    static Cup c1;
    static Cup c2;

    static
    {
        c1 = new Cup(1);
        c2 = new Cup(2);
    }
}

叫做static明确初始化。这种初始化有两个注意的地方:

class Cups
{
    static Cup c1;
    static Cup c2;

    static
    {
        c1 = new Cup(1);
        c2 = new Cup(2);
    }
}

叫做static明确初始化。这种初始化有两个注意的地方:

(1) 这种初始化仅会被执行一次。

(2) 执行的时间为首次产生class对象的时候,或者为首次访问该class的static成员的时候


[实体初始化]

对于non-static型的变量,Java也提供了类似static型初始化的语法。

public class Main
{

    String s;

    {
        s = "good morning!";

        System.out.println("initialized.");
    }

    Main()
    {
        System.out.println("constructor.");
    }

    public static void main(String[] args)
    {
        System.out.println("entry.");
        Main m = new Main ();
    }
}

 

该程序输出:

 

 

entry.
initialized.
constructor.

执行顺序一目了然。

[继承构造函数]

如果一个类继承自某个基类,而又没有默认构造函数的话,系统会自动添加一个默认构造函数,这个默认构造函数调用基类的构造函数,比如

class A
{
    A() {}
}

class B extends A
{
    //
在这里会默认添加:
    // B() { super(); }

}

这个和C++略有不同,C++中构造函数是不能被继承的。

其实,这个技术的实际情况是:Java编译器会自动在derived class构造函数中插入对base class构造函数的调用动作。

[缓式初始化]

其实也不算什么技术了,就是一种提高性能的方法。

对一个对象初始化有三种方式:

(1) 在对象定义的地方初始化。
(2) 在类的构造函数中。
(3) 在实际需要用到该对象的地方。

其中方式(3)就叫做缓式初始化(lazy init)

class A
{
    String _s;
    A(String s)
    {
        _s = s;
    }

    public String toString()
    {
       
return _s;
    }
}

class B
{
    A a;
   
   
public String toString()
    {
        a =
new A("hello, world");  // lazy init
        return a.toString();
    }
}

public class Main
{
   
public static void main(String[] args)
    {
        B b =
new B();
        System.out.println(b);
    }
}

 

[再议清理]

[再议清理]

垃圾清理这东西没准儿。所以:如果你希望发生清理动作,请自行撰写清理用的函数。

比如

class A
{
    void cleanup()
    {
        //
添加清理
    }
}

class B extends A
{
    void clearup()
    {
        //
添加清理
        super.cleanup();
    }
}

public class Main
{
    public static void main(String[] args)
    {
        B b = new B();
        try
        {
            //
代码和异常处理
        }
        finally
        {
            b.cleanup();
        }
    }
}

class A
{
    void cleanup()
    {
        //
添加清理
    }
}

class B extends A
{
    void clearup()
    {
        //
添加清理
        super.cleanup();
    }
}

public class Main
{
    public static void main(String[] args)
    {
        B b = new B();
        try
        {
            //
代码和异常处理
        }
        finally
        {
            b.cleanup();
        }
    }
}

如果一个类继承自某个基类,而又没有默认构造函数的话,系统会自动添加一个默认构造函数,这个默认构造函数调用基类的构造函数,比如

class A
{
    A() {}
}

class B extends A
{
    //
在这里会默认添加:
    // B() { super(); }

}

这个和C++略有不同,C++中构造函数是不能被继承的。

其实,这个技术的实际情况是:Java编译器会自动在derived class构造函数中插入对base class构造函数的调用动作。

[缓式初始化]

其实也不算什么技术了,就是一种提高性能的方法。

对一个对象初始化有三种方式:

(1) 在对象定义的地方初始化。
(2) 在类的构造函数中。
(3) 在实际需要用到该对象的地方。

其中方式(3)就叫做缓式初始化(lazy init)

class A
{
    String _s;
    A(String s)
    {
        _s = s;
    }

    public String toString()
    {
       
return _s;
    }
}

class B
{
    A a;
   
   
public String toString()
    {
        a =
new A("hello, world");  // lazy init
        return a.toString();
    }
}

public class Main
{
   
public static void main(String[] args)
    {
        B b =
new B();
        System.out.println(b);
    }
}

 

[再议清理]

[再议清理]

垃圾清理这东西没准儿。所以:如果你希望发生清理动作,请自行撰写清理用的函数。

比如

class A
{
    void cleanup()
    {
        //
添加清理
    }
}

class B extends A
{
    void clearup()
    {
        //
添加清理
        super.cleanup();
    }
}

public class Main
{
    public static void main(String[] args)
    {
        B b = new B();
        try
        {
            //
代码和异常处理
        }
        finally
        {
            b.cleanup();
        }
    }
}

class A
{
    void cleanup()
    {
        //
添加清理
    }
}

class B extends A
{
    void clearup()
    {
        //
添加清理
        super.cleanup();
    }
}

public class Main
{
    public static void main(String[] args)
    {
        B b = new B();
        try
        {
            //
代码和异常处理
        }
        finally
        {
            b.cleanup();
        }
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值