エンジニアのひよこ_level10

【毎日更新!】新卒3年目エンジニアブログです!

【Java】ArrayListのclone()の戻り値がObjectの理由(リリース時期)【845日目】

ArrayListのcloneの実装に疑問を持った

Javaは、基本のライブラリはソースコードが見れますので、コードを追ってました。

ArrayList.class

    /**
     * Returns a shallow copy of this {@code ArrayList} instance.  (The
     * elements themselves are not copied.)
     *
     * @return a clone of this {@code ArrayList} instance
     */
    public Object clone() {
        try {
            ArrayList<?> v = (ArrayList<?>) super.clone();
            v.elementData = Arrays.copyOf(elementData, size);
            v.modCount = 0;
            return v;
        } catch (CloneNotSupportedException e) {
            // this shouldn't happen, since we are Cloneable
            throw new InternalError(e);
        }
    }

public Object clone()

ここの部分。これは、 public ArrayList<?> clone() と書いても、 ArrayListObjectのサブクラス(子である。Objectを継承してるってこと)なので、オーバーライドしても戻り値を変えられると思った。

より狭い範囲で戻り値を指定できるので、変えたほうが良いと思ったのですが、なんでこうなっているのだろうと思いました。
JJUG(日本Javaユーザーグループ)の方に質問したところ、すっごく納得のいく説明を頂きました!

後方互換(リリース時期の都合)

ArrayListは1.4で実装されたのですが、cloneの戻り値としてObject以外が使えるようになったのが1.5からだそうです。
従って、下位互換を保つためにも、戻り値をObjectのままにしておく必要がある。

こう聞いて、めっちゃ納得しました!

私達としては、コード読む時に気をつけなければならないのもそうですが、こういったことを考えながら作っているという歴史を知る機会になって非常に良い時間になりましたφ(・