- PR -

Object#clone()メソッドについて

投稿者投稿内容
Guri
会議室デビュー日: 2007/01/16
投稿数: 12
投稿日時: 2007-02-28 19:42
sawatさん 回答ありがとうございます。

引用:

sawatさんの書き込み (2007-02-28 18:43) より:

個人的に気になるのを挙げるなら、

  • RuntimeExceptionがExceptionのサブクラスであること。
  • java.util.Dateやjava.awt.Pointなど不変クラスであるべきいくつかのクラスが可変であること。
  • AWTとSwingで2つのGUIツールキットがあること。
他にもあった気がするけど、今思いつくのはこんなところ。

Serializableに比べればどれも実害は少なそうですね。


Serializableを実装し忘れるぐらいならば、いっそObjectにSerializableを実装しておけば良いのにと思うのですが。これは別スレッドをたてます。

RuntimeExceptionがExceptionのサブクラスであること、
これは個人的に、あまり気になりませんが、java.util.Date、java.awt.Pointは
確かにimmutableでよいかなと思いますね。

ただ、java.awt.PointはAWTやSwingのGUI処理で頻繁に使われているので、
VMの速度が今より遅かったころの名残で、描画やイベント処理で、その都度
オブジェクトを生成するオーバーヘッドを考慮してなのかと、勝手に思っています。

java.awt.Pointやjava.awt.Rectangleのメンバー変数が、アクセサメソッドを通さずに、
publicでアクセス可能なあたりも同様の理由と考えています。

AWTとSwingで2つのGUIツールキットがあることは、JAVA史の変遷から、
まぁ、仕方がないかと思っていますが。

とここまで書いてきて、印刷APIは非常に散漫で酷いですね。
もし、印刷APIをご存知でなく、AWTとSwingが気になるタチでしたら、
印刷APIは覗かないことをお勧めします。

なにはともあれ、皆様ありがとうございました。
かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2007-02-28 22:13
かなり余談になるかもしれませんが、
JSRでjavax.timeで始まる新しい日付APIの仕様を策定中です。
http://jcp.org/en/jsr/detail?id=310
英文が苦手なので全部読んでいませんが、多分immutableになると思いますよ。


sawat
大ベテラン
会議室デビュー日: 2006/08/02
投稿数: 112
投稿日時: 2007-03-01 01:21
引用:

Guriさんの書き込み (2007-02-28 19:42) より:
ただ、java.awt.PointはAWTやSwingのGUI処理で頻繁に使われているので、
VMの速度が今より遅かったころの名残で、描画やイベント処理で、その都度
オブジェクトを生成するオーバーヘッドを考慮してなのかと、勝手に思っています。


これは、実際まったくの逆で、可変であるために大量のコピーを生成しなければならず、パフォーマンス上のペナルティになっています。
その辺の話はEffective Javaに載っていたと思うので、読んでみるといいと思います。
Guri
会議室デビュー日: 2007/01/16
投稿数: 12
投稿日時: 2007-03-01 13:53
情報提供ありがとうございます。
Effective Javaは、今度読んでみます。

引用:

sawatさんの書き込み (2007-03-01 01:21) より:
引用:

Guriさんの書き込み (2007-02-28 19:42) より:
ただ、java.awt.PointはAWTやSwingのGUI処理で頻繁に使われているので、
VMの速度が今より遅かったころの名残で、描画やイベント処理で、その都度
オブジェクトを生成するオーバーヘッドを考慮してなのかと、勝手に思っています。


これは、実際まったくの逆で、可変であるために大量のコピーを生成しなければならず、パフォーマンス上のペナルティになっています。
その辺の話はEffective Javaに載っていたと思うので、読んでみるといいと思います。



可変であるために大量のコピーを生成しなければならず、パフォーマンス上のペナルティになるということは、java.awt.geomパッケージのクラス群も、おそらくそういうことになるのでしょう。

これは、java.awt.Graphics2Dの実装や精度によるものかもしれませんが、
下記コードのパフォーマンスが異なるのも、そのせいかもしれませんね。
(下記コードの描画部分のみをfor分でまわすと、私の環境では、常にdrawLine()の方が良いパフォーマンスを示します。)

コード:
private static final java.awt.Shape SHAPE = new Line2D.Float(0.0f, 0.0f, 1024.0f, 0.0f);

java.awt.Graphics2D g2d = ...
g2d.drawLine(0, 0, 1024, 0);
//g2d.draw(SHAPE);



この話を聞いて、java.awt.Pointやjava.awt.Rectangle等が、カプセル化を完全放棄した自分なりの理由が崩壊してしまいました。

ということで、java.awt.Pointやjava.awt.Rectangleのソースを見てみたものの、メンバ変数にpublicアクセス修飾子をつけている理由には、まったく触れられていませんでした。対極的に、java.awt.geomパッケージのクラスは、大部分がカプセル化されているんですが。

詳細はEffective Javaを読んでみますが、Effective Javaには、こういったケースの理由についても言及されいるのでしょうか。

メンバー変数にprivate,protectedでも、フレンドリでもなく、publicアクセス修飾子をつける実装なんて、初心者か、何らかの明確な意図がないとしないと思うのですが。。

メリットとして、コードが少々簡便になる位しか思いつかず、カプセル化を放棄する理由としては、弱いなと感じます。
sawat
大ベテラン
会議室デビュー日: 2006/08/02
投稿数: 112
投稿日時: 2007-03-01 16:29
引用:

Guriさんの書き込み (2007-03-01 13:53) より:
この話を聞いて、java.awt.Pointやjava.awt.Rectangle等が、カプセル化を完全放棄した自分なりの理由が崩壊してしまいました。


いえ、カプセル化を放棄した理由は想像通りであっていると思います。
で、後で問題が発覚したが互換性維持のために修正できない。
というのが実際のところだと思っています…。

ちなみにj2se1.1の時点で、intをとるsetterや、出力引数を使うgetterが追加されて、ライブラリ内部ではこちらを使うようになっています。
なので、実際のところはそれほどパフォーマンスに影響はないのかもしれません。

# 出力引数とかはあまりjava的でなく、美しいメソッドではありませんが…。
nagise
ぬし
会議室デビュー日: 2006/05/19
投稿数: 1141
投稿日時: 2007-03-01 17:01
このあたりはAPI設計上のアンチパターンとして、今後の新言語に生きてくると思うのですけどね。
やはり、これだけ膨大な仕様を互換性を保ちつつ拡張するというのは
相当に辛いことだと思います。Java中の人には足を向けて眠れませんね。

# Color.whiteとかの命名規約に沿っていない定数とかも時代を感じさせる代物ですよね。
Guri
会議室デビュー日: 2007/01/16
投稿数: 12
投稿日時: 2007-03-01 18:15
sawatさん ありがとうございます。

引用:

ちなみにj2se1.1の時点で、intをとるsetterや、出力引数を使うgetterが追加されて、
ライブラリ内部ではこちらを使うようになっています。
なので、実際のところはそれほどパフォーマンスに影響はないのかもしれません。


ライブラリ内部というのは、nativeでの話ですか?

というのは、手元のjdk5のSwingのソースを検索すると、Rectangleのx,yプロパティに直接アクセスしている箇所が、
相当数見つかるのです。
r.x = ...; r.y = ...;等。

j2se1.1以降にsetter,getterのアクセサメソッドイディオムが導入される前から、
アクセス修飾子はあったでしょうに、よりにもよってなぜpublicだったのでしょうね。
フレンドリくらいだったら、その後、ごまかせたでしょうに。

とりあえず、紹介していただいた本を読んでみます。

引用:

やはり、これだけ膨大な仕様を互換性を保ちつつ拡張するというのは
相当に辛いことだと思います。Java中の人には足を向けて眠れませんね。


同感です。

引用:

# Color.whiteとかの命名規約に沿っていない定数とかも時代を感じさせる代物ですよね。


ですね。

ただ、2000年以降とか作成されたのが、比較的新しいAWT初心者向け解説サイトで、
Color.whiteとか見るとどうにも。。。

# 命名規約についての余談ですが、どこかのサイトで処理内容と無関係で、
処理内容を一切連想させないI_001,I_002,E_010のような変数(定数ではない)を
使用していたのを見たときは、ドン引きしました。。
しかも、プロフィールがJAVA言語講師とかで。。。

まさ
ベテラン
会議室デビュー日: 2002/11/15
投稿数: 74
投稿日時: 2007-03-14 13:54
まさです。

>下記のようなコードがあったとして、clone()可能ならば、clone()を呼び出すような方法はあるでしょうか。

えっと、clone() は Object が持つメソッドだから、
コード:

if (list instanceof Clonable) {
    copyList = (List) list.clone();
}


じゃないの?

なんか違ってる?

スキルアップ/キャリアアップ(JOB@IT)