- PR -

オーバーライドについて

投稿者投稿内容
skt
会議室デビュー日: 2004/12/06
投稿数: 12
投稿日時: 2004-12-07 10:51
かつのり様、takamaro様、tak3様
ご返信ありがとうございます。

現在調査中なのですが、
tak3様にご指摘いただいた「classファイルそのものが悪い(古い)」
ことは想定していませんでした・・・。
VSSでバージョン管理しているのですが、そこに不備があったのかもしれません。
対象モジュールを修正せず、リコンパイルのみ行って再度確認してみます。
未記入
常連さん
会議室デビュー日: 2004/08/03
投稿数: 21
投稿日時: 2004-12-07 11:09
いきなりですが、試してみましたが、普通になりましたよ!

・Windows2000Pro
・JDK1.4.2
・eclips2.1

で行ないました。
実行クラスはHttpServletを継承していませんけど。。。
skt
会議室デビュー日: 2004/12/06
投稿数: 12
投稿日時: 2004-12-07 13:37
自己レスです。

下記の調査を行ってみました。
 @バージョン管理しているクラスファイルで動作確認 ← 念のためもう一度
 Aクラス親 のみをリコンパイルして動作確認
 Bクラス子1 のみをリコンパイルして動作確認
 Cクラス子2 のみをリコンパイルして動作確認
 Dクラス子1・子2をリコンパイルして動作確認
 Eクラス親・子1・子2をリコンパイルして動作確認
クラス親・クラス子1・クラス子2以外は全てバージョン管理しているものを使用しました。
結果、@〜E全てで同じ現象が再発してしまいました。
どうやらクラスファイルが悪い(古い)わけではなさそうです。

次にクラスファイルを全てバージョン管理している物に戻して、
WAS起動後の初回アクセスと2回目アクセスを逆にしてみました。つまり、
 WASを起動後の初回アクセスで、RequestParameter"aaa" が "2"
  → count = new クライアント2().getCount() = 5000となる「はず」
 2回目のアクセスで、RequestParameter"aaa"が "1"のとき、
  → count = new クライアント1().getCount() = 1000となる「はず」
で動かしてみたところ、これが正しく動作しました。
(この後、3回目としてRequestParameter"aaa" が "2" でアクセスしたところ、問題なく 5000が返ってきました)
クライアント1クラスとクライアント2クラスの違いといえば、
子クラスを保持するフィールドがstaticか非staticかどうかです。

以上のことから
 ・クラス 子1 でもgetCountメソッドをオーバーライドする
 ・初回アクセスが「クライアント2」
であれば、正常に動作するようなのです。


>・Windows2000Pro
>・JDK1.4.2
>・eclips2.1
>で行ないました。
お名前はわかりませんが、ご返信ありがとうございます。
JDKのバージョンは1.4.2で試されたのですね。
環境さえあればぜひ試してみたいのですが・・・。
tak3
ベテラン
会議室デビュー日: 2004/04/15
投稿数: 80
お住まい・勤務地: 菜の花・銀杏
投稿日時: 2004-12-07 16:21
今回のケースとは関係ないですが、ふと思い出したJavaHouseの過去ログ
コード:
public class Foo{
    void print(Foo foo){
        System.out.println("Foo.foo");
    }
}

public class Bar extends Foo{
    void print(Foo foo){
        System.out.println("Bar.foo");
    }
    void print(Bar bar){
        System.out.println("Bar.bar");
    }
}

public class Main{
    public static void main(String[] args){
        Foo foo = new Foo();
        Bar bar = new Bar();
        Foo fooBar = new Bar();

        System.out.println("Foo");
        foo.print(foo);	// ※1 Foo.foo
        foo.print(bar);	// ※2 Foo.foo
        System.out.println();

        System.out.println("Bar");
        bar.print(foo);	// ※3 Bar.foo
        bar.print(bar);	// ※4 Bar.bar
        System.out.println();

        System.out.println("FooBar");
        fooBar.print(foo);	// ※5
        fooBar.print(bar);	// ※6
    }
}


ジャカジャン♪
さて、※5、※6では、画面にどのように出力されるでしょうか。
答えはxx分後
ジャカジャン♪
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2004-12-07 22:56
unibon です。こんにちわ。

引用:

sktさんの書き込み (2004-12-06 22:38) より:
<<環境>>
・Windows2000Pro
・WebSphere3.5
・JDK1.2.2


WebSphere ということは、(Sun ではなく)IBM の JDK ということでしょうか。コンパイラーのバグか、実行環境のバグかも分からない感じですよね。最新のバージョンでコンパイルしたり、ためしに Sun の javac でコンパイルしてみてはどうでしょうか。
しかし、実行順序でバグがでないと書かれていることから考えると、コンパイル環境のバグではないということになるかもしれません。
以下、昔のことなので私の妄想も入っていますが、1.2.2 の頃の IBM の JDK は結構不安定だった気がします。WebSphere は使ったことはないのですが、IBM JDK の 1.2.2 の上でプログラムを動かしていても、なんだか挙動が変だった印象が強かったです。
tak3
ベテラン
会議室デビュー日: 2004/04/15
投稿数: 80
お住まい・勤務地: 菜の花・銀杏
投稿日時: 2004-12-08 00:34
Mainだけのクラスで。
コード:
public static void main(String[] args) {
    System.out.println(new クライアント1().getCount());
    System.out.println(new クライアント2().getCount());
    System.out.println(new クライアント1().getCount());
}

と

public static void main(String[] args) {
    System.out.println(new クライアント2().getCount());
    System.out.println(new クライアント1().getCount());
    System.out.println(new クライアント2().getCount());
}


の出力結果は確認されましたか?
引用:

インスタンス生成は全てFactoryクラスに任せた構造になっています。


ということですが、正しいインスタンスを生成できてますか?
skt
会議室デビュー日: 2004/12/06
投稿数: 12
投稿日時: 2004-12-08 02:35
unibon様、tak3様
ご返信ありがとうございます。

>ためしに Sun の javac でコンパイルしてみてはどうでしょうか。
それは考えていませんでした。一度試してみます。

>しかし、実行順序でバグがでないと書かれていることから考えると、コンパイル環境の>バグではないということになるかもしれません。
>以下、昔のことなので私の妄想も入っていますが、1.2.2 の頃の IBM の JDK は結構不>安定だった気がします。
実は今回投稿した現象以外にも、
継承が絡んだ箇所でおかしい動きをしたことがありました。
モジュール構成も今回のケースに似ていて、
親クラスのメソッドを子クラスでオーバーライドしているにもかかわらず、
子クラスのインスタンスから該当メソッドを実行した場合、
親クラスの処理が動く というケースです。
ちなみにそのときは、親クラスのメソッドをabstractにして、
子クラス全てに具象メソッドをオーバーライドしたら直りました。

>出力結果は確認されましたか?
>正しいインスタンスを生成できてますか?
Mainクラスからテストしたわけではありませんが、
今回問題となっているgetCount()メソッド以外にもメソッドは多数存在し、
getCount()メソッド以外は正常に動作しています。
また、以前の投稿にも書きましたが、
WAS起動後の処理順序によっては正常に動く場合もあるので、
ご指摘の内容については問題ないと考えています。
skt
会議室デビュー日: 2004/12/06
投稿数: 12
投稿日時: 2004-12-09 14:26
自己レスです。

結局以前行ったのと同じ、
「親のメソッドをabstractに変更し、全ての子クラスで実定義する」
対応で逃げました。原因はわからずじまいですが・・・
ただもちろん調査は継続いたします。

unibon様からご指摘いただいたsunコンパイラはまだ試していないのですが、
このご指摘は「コンパイルレベルから検証する」きっかけを与えてくださり、
良いヒントになりました。
今のコンパイル環境ですが、JDKが 
 「WebSphere3.5に付属の、IBM製JDK1.2.2」 で、
 「Ant 1.6.1」
を使用して行っています。
これをAntを使わず直接javacで行う等の検証を行ってみようと思います。

その他の皆様も、ご返信どうもありがとうございました。

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