页面

2010-07-28

java构造函数

  1. 每个类都是调用自己的一系列构造函数中的一个。
  2. 被调用的构造函数中没有super调用的话,将先依次调用基类的默认构造函数,且都是在调用完基类构造函数后才执行本身构造函数内的代码。
  3. 任何类,只要定义了一个带参构造函数,同时没有定义默认构造函数,那么java不会为其提供默认构造函数。
下面是从这里整理的:
  1. 子类在初始化的时候,Java将自动调用基类的默认构造器;
  2. 当基类只有带参数的构造器时,子类的构造器必须显式的利用super关键字调用基类的构造器;
  3. 当基类有多个构造器且其中包含默认构造器,而且子类不显式的调用基类的构造器时,Java将自动调用基类的默认构造器;即:父类并不一定要有默认的无参数构造器。分为两种情况:
    1. 有默认构造器,那么子类在不显示调用有参父类构造器的时候,会隐式调用该默认构造器。
    2. 没有默认构造器,那么子类必须显示调用有参父类构造器。
又:隐式调用父类无参数构造器的情况:
  1. 父类仅有无参数构造器,子类肯定会隐式调用;
  2. 父类有多个构造器,且其中包含无参数构造器,且子类没有显式调用父类的有参构造器,那么会隐式调用无参数构造器。

2010-07-24

Java注释

Java Annotation技术旨在提供一个不影响程序语义而可以指导外部工具反射地做出判断的一种技术。这里是个入门的例子:
http://download.oracle.com/docs/cd/E17476_01/javase/1.5.0/docs/guide/language/annotations.html

2010-07-23

用rpl命令递归地替换在多个文件中的字符串

$ rpl -Rwd -x'.txt' 'old_string' 'new_string' grades/

2010-07-21

eshell

history

The ‘history’ command shows all commands kept in the history ring as numbered list. If the history ring contains eshell-history-size commands, those numbers change after every command invocation, therefore the ‘history’ command shall be applied before using the expansion mechanism with history numbers.

The n-th entry of the history ring can be applied with the ‘!n’ command. If n is negative, the entry is counted from the end of the history ring.

‘!foo’ expands to the last command beginning with foo, and ‘!?foo’ to the last command containing foo. The n-th argument of the last command beginning with foo is accessible by !foo:n.

boulevard, avenue, street, road

A boulevard is a broad city street that is lined with trees and landscaped. Many boulevards have an island of trees, grass, or flowers down the center, which divides the traffic.

A street is a public way in a city or a town. A street, usually, is accompanied by a sidewalk.

A road is a narrow, usually paved strip of land, used for transportation. Roads are, generally, found outside of urban areas.

An avenue is a broad passageway bordered by trees.

2010-07-17

Java clone方法既深copy

Object类中的clone方法是protected的,要提供给外部使用,必须(直接或间接)实现标志接口java.lang.Cloneable。

容器类(ArrayList等)提供的clone方法只是浅copy(shallow copy),即重新生成并保存了指向目标类的一系列指针。要实现深copy,必须通过新容器对象的添加方法添加目标对象的clone。如:list_x.add(obj.clone())。即目标对象应很好地实现clone方法。但目前,传统的clone方法设计模式在泛型编程时会出现问题:
public class Foo<T extends Cloneable> {
    T obj;
    public Object clone() {
        obj.clone();
    }
}
这段代码无法通过编译:obj继承有Object的clone方法,但不能从外部调用;Cloneable是个空的、标志接口,没有声明clone方法。所以,obj没有公开的clone方法供调用。

一个设计策略是由Cloneable接口派生一个接口,其中声明clone方法,然后泛型约束到该接口。如下列代码所示:
public interface IClone implements Cloneable {
    public Object clone();
}

public class Foo<T extends IClone> {
    T obj;
    public Object clone() {
        obj.clone();
    }
}

一个更加健壮的clone方法实现是通过反射技术,如下列代码:
public MyClass<T> clone( ) throws CloneNotSupportedException { 

    MyClass<T> clon = null; 

    try {  
         clon = (MyClass<T>)super.clone(); 
    } catch (CloneNotSupportedException e) {  
         throw new InternalError();  
    } 

    try { 
       Class<?> clzz = this.field_a.getClass(); 
       Method meth = clzz.getMethod("clone", new Class[0]); 
       Object dupl = meth.invoke(this.field_a, new Object[0]); 
       clon.field_a = (T)dupl;  
    } catch (Exception e) { 
       throw new CloneNotSupportedException (e.toString()); 
    }

}

实际编程中,很难事先设计周全,经常遇到涉及类没有完整实现clone方法的情况,此时,可使用下列通过序列化技术实现的深copy方法(注意:此方法要求被clone的对象实现java.io.Serializable接口):
import java.io.*;
import java.util.*;

/**
   This class is a tool to clone an object deeply.
*/
public class Cloner {

    private Cloner() {
    }

    /**
       This method returns a deep copy of an object.
       @param src the source object to be cloned
       @return a deep copy of src
    */
    public static Object clone(Object src) throws Exception {

 ObjectOutputStream oos = null;
 ObjectInputStream ois = null;

 try {

     ByteArrayOutputStream bos = new ByteArrayOutputStream();
     oos = new ObjectOutputStream(bos);
     // serializing and passing the object
     oos.writeObject(src);
     oos.flush();
     ByteArrayInputStream bin = new ByteArrayInputStream(bos.toByteArray());
     ois = new ObjectInputStream(bin);
     // returning the new object
     return ois.readObject();

 } catch (Exception e) {
     System.out.println("Exception in Cloner: " + e);
     throw(e);
 } finally {
     oos.close();
     ois.close();
 }
    }

}

2010-07-02

上帝为什么不奖赏好人

题记:人为善,福虽未至,祸已远离; 人为恶,祸虽未至,福已远离。

原文在这里

1963年,一位叫玛莉•班尼的女孩写信给《芝加哥论坛报》,因为她实在搞不明白,为什么她帮妈妈把烤好的甜饼送到餐桌上,得到的只是一句“好孩子”的夸奖,而那个什么都不干,只知捣蛋的戴维(她的弟弟)得到的却是一个甜饼。她想问一问无所不知的西勒•库斯特先生,上帝真的是公平的吗?为什么她在家和学校常看到一些像她这样的好孩子被上帝遗忘了。

西勒•库斯特是《芝加哥论坛报》儿童版栏目的主持人,十多年来,孩子们有关“上帝为什么不奖赏好人,为什么不惩罚坏人”之类的来信,他收到不下千封。每当拆阅这样的信件,他心就非常沉重,因为他不知该怎样回答这些提问。正当他对玛莉小姑娘的来信不知如何回答是好时,一位朋友邀请他参加婚礼。 也许他一生都该感谢这次婚礼,因为就是在这次婚礼上,他找到了答案,并且这个答案让他一夜之间名扬天下。

西勒•库斯特是这样回忆那场婚礼的: 牧师主持完仪式后,新娘和新郎互赠戒指,也许是他们正沉浸在幸福之中,也许是两人过于激动。总之,在他们互赠戒指时,两人阴错阳差地把戒指戴在了对方的右手上。牧师看到这一情节,幽默地提醒:右手已经够完美的了,我想你们最好还是用它来装扮左手吧。

西勒•库斯特说,正是牧师的这一幽默,让他茅塞顿开。右手成为右手,本身就非常完美了,是没有必要把饰物再戴在右手上了。那些有道德的人,之所以常常被忽略,不就是因为他们已经非常完美了吗?后来,西勒﹒库斯特得出结论,上帝让右手成为右手,就是对右手最高的奖赏,同理,上帝让善人成为善人,也就是对善人的最高奖赏。

西勒•库斯特发现这一真理后,兴奋不已,他以“上帝让你成为好孩子,就是对你的最高奖赏”为题,立即给玛莉•班尼回了一封信,这封信在《芝加哥论坛报》刊登之后,在不长的时间内,被美国及欧洲一千多家报刊转载,并且每年的儿童节他们都要重新刊载一次。

前不久,一位中国人不知在什么地方发现了这封信,读后的网页上留言说:“中国民间有一句古话,叫「恶有恶报,善有善报,不是不报,时候未到」。我曾经对恶人迟迟得不到报应感到迷惑不解。

现在我终于明白,因为 : "让恶人成为恶人, 就是上帝对他们的惩罚。”

『人为善,福虽未至,祸已远离; 人为恶,祸虽未至,福已远离』