- - PR -
DataOutputStreamへのCast
1
| 投稿者 | 投稿内容 | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2003-03-21 21:22
BufferedOutputStream[i]からDataOutputStreamのキャストでエラーが出てしまいます。対処の仕方の分かる方いらっしゃいませんか。
具体的には //construcotr this.inStream = new BufferedReader(new FileReader(inFile)); this.outStream=new BufferedOutputStream[n]; for(int i=0;i<n;i++){ String filename=filePref+(i+1); this.outStream[i]= new BufferedOutputStream(new DataOutputStream(new FileOutputStream(filename)),bSize); レコードを読みこむ this.seedRec.readObject(this.inStream); レコードクラスで受け取る public void readObject(Reader r)throws IOException{ String s=""; BufferedReader br = (BufferedReader)r; try{ s= br.readLine(); if(s ==null) return; StringTokenizer lineTokenizer = new StringTokenizer(s); this.id = Integer.parseInt(lineTokenizer.nextToken()); this.salary = Float.parseFloat(lineTokenizer.nextToken()); this.name = lineTokenizer.nextToken(); }catch(IOException e){} } そして、また元のクラスに戻りソート後書きこむ outputItem.writeObject(outStream[i]); そしてレコードクラスでjava.lang.ClassCastException: java.io.BufferedOutputStream public void writeObject(OutputStream os) throws IOException { DataOutputStream dos = (DataOutputStream)os; try { dos.writeInt(this.id); dos.writeFloat(this.salary); dos.writeInt(this.name.length()); dos.writeChars(this.name); dos.flush(); } catch (IOException e) { } } | ||||||||||||
|
投稿日時: 2003-03-21 22:11
こんにちは。
>BufferedOutputStream[i]からDataOutputStreamのキャストでエラーが出てしまいます。 BufferedOutputStream[i]からDataOutputStreamへキャストしている個所が見当たりま せんが??? writeObjectメソッドの DataOutputStream dos = (DataOutputStream)os のことなら、 DataOutputStream dos = new DataOutputStream(os) では? クラスの継承関係をヘルプで見直してみては? あと、 this.outStream[i]= new BufferedOutputStream(new DataOutputStream(new FileOutputStream(filename)),bSize); は、 this.outStream[i]= new BufferedOutputStream(new FileOutputStream(filename),bSize); ではだめ? 違ってたらごめんなさい。 エラーがでるなら、Javaの場合はエラーがでるソースと行数がわかるので、エラーの 個所は特定できるでしょう。具体的にと前置きしてるわりに、不要な個所のソースも含め貼 り付けるのは、いかがなものかと。もっと不具合を絞り込んで、それでもわからなければ わからない個所を簡潔に質問したほうがいいのでは?(^^; キャストのエラーがでるという程度で、解析してといわんばかりにソース貼り付けて、 具体的に何をしたという説明もなく、わかる方いませんか?というのはいかがなものかと 思うのですが?(^^; | ||||||||||||
|
投稿日時: 2003-03-22 05:21
不要な所を書き込んだつもりはありません。なぜ"new"にしなかったかというと、読み込みと同様、Distrubutorクラスとのつながりがあるからです。まず、クラスDistributorのコンストラクタで、ファイルを指定したbufferサイズで読み、n個の書き込みファイルを作ります。ここで、DataOutputStreamをラップしておく必要があると考えられます。このことは重要だと思い、表示しました。次に、DistributorクラスのメソッドDistributeでBinariTree(HeapArea)を作ります。その次にreadObject(Sortable)で、interface SortableのimplementationクラスRecordで、読み込みます。もし、ここでnewを使うと、レコードは一つしか読み込みません。ここで、読み込んだレコードは、Distributeでしていした回数、(heapサイズ)を繰り返したのち、ソートされます。ここでは、サラリーの高い順にソートされるので、Maxナンバーから順にファイルに書き込まれます。このDistributeで受けたMaxをRecordクラスで書き込みます。この時、Castに失敗します。
以上のように、2つのクラスとのつながりがあるので、2つのクラスを表示しました。無駄はないはずです。逆に書かないと返って分からなくなると思います。maruさんのおっしゃっていることは、一番最初にやったことです。それで駄目だったので、前回表示した結果になりました。どなたか、きっとこのことを理解されている方がいらっしゃるかと思い、投稿しました。writeObjectのparameterをDataOutputStreamにする手もあると思いますが、そうするとinterfaceSortableも変えることになります。 maruさんのおっしゃる >BufferedOutputStream[i]からDataOutputStreamのキャストでエラーが出てしまいます。 BufferedOutputStream[i]からDataOutputStreamへキャストしている個所が見当たりま せんが??? は意味がわかりません。iはrunの数ですが... 改めて、どなたか他にいい案をお持ちの方はいらっしゃいませんか。 | ||||||||||||
|
投稿日時: 2003-03-22 07:27
いい案も何も、BufferedOutputStream を DataOutputStream にキャストすることは不可能です。これらは継承関係にないのですから。maruさんが書いてるように、Java APIのヘルプを見れば次のように載ってます。
このように、両者は親子関係になく、兄弟関係なのでキャストはできません。
念のためですが、コンストラクタで new BufferedOutputStream(new DataOutputStream(...),bSize); とやっても、継承関係はまったく変わりませんので、キャストできないことにも変わりありません。 今回のコードは、maruさんが書いているように、下記のようにするだけで十分だと思いますが、何か問題がありますか?
| ||||||||||||
|
投稿日時: 2003-03-22 09:12
こんにちは。
どの部分のことかはだいたいわかりましたが、あえて文書の頭にこのようなことを書 きました。この問題を考えたとき、BufferedOutputStreamをDataOutputStreamで キャストしている個所(エラーが出ているといわれる個所)をさがして、 ここにかかれている os は OutputStream だが、言われているのは DataOutputStream dos = (DataOutputStream)os のことかと推測を立てて、ソース を逆に追っかけて ・・・ outStream[i]に BufferedOutputStreamを入れているのが あって・・・と、やっと(といってもそんなに時間のかかるものでもないが)BufferedOutputStream と DataOutputStream が結びつきました。 今回の問題は、「キャストでエラーが出ている」という原因とその個所がはっきりしている はずです。その問題と、Distrubutorクラス、ファイルを指定したbufferサイズ、 BinariTree(HeapArea)、サラリーの高い順・・・うんぬんかんぬん・・・関係ないの ではないですか?今作られているソースを貼り付けられたのでしょうが、質問する場合は 問題部分を整理して、 BufferedOutputStream outStream = new BufferedOutputStream( new DataOutputStream(new FileOutputStream(filename)),bSize); DataOutputStream dos = (DataOutputStream)outStream; キャストでエラーが出てしまいます。 程度にまとを絞って掲示板にあげたほうがいいとおもいますよ。そうすれば、もっと気楽 にアドバイスしてくれる人は増えると思います(^^; そう思ったのは私だけではないと思います。 >maruさんのおっしゃっていることは、一番最初にやったことです。それで駄目だった ??? [ メッセージ編集済み 編集者: maru 編集日時 2003-03-22 09:50 ] | ||||||||||||
|
投稿日時: 2003-03-22 13:16
>DataOutputStreamをラップしておく必要がある
ここで言っているラップをどういう意味で使われているのかは、正確にはわかりませんが、 これは単に、BufferedOutputStreamのコンストラクタの引数に OutputStream型のクラス (BufferedOutputStream と DataOutputStreamの親でもある)を渡しているだけではない ですか?このように書いても outStream[i] が DataOutputStream になるわけではないと 思いますが。 私もJavaのクラス継承とキャストについて、正確に理解できているかは不安ですが、 自分のためにも再確認してみました。 OutputStream と BufferedOutputStream と DataOutputStream は、おそらく以下の ソースのような関係になると思います。 ※逆コンパイルしたわけではないのでわかりませんが・・・。 今回は、どちらかといえばパターンBに近いのではないでしょうか? <参考ソース> // 親クラス(OutputStreamに相当) class Parent { int a; public void ABC(){ } } // 子クラス1(BufferedOutputStreamに相当) class Child1 extends Parent{ Parent p; public Child1(){} public Child1( Parent p ){ this.p=p; } public void DEF(){ } } // 子クラス2(DataOutputStreamに相当) class Child2 extends Parent{ Parent p; public Child2(){} public Child2( Parent p ){ this.p=p; } public void GHI(){ } } // テスト class Test{ public static void main(String[] args){ // パターンA Parent p1 = new Child1(); // Child1オブジェクトを親の Parent型の変数にいれる。親子関係なので可能。 // p1.DEF();//コンパイル時にエラー。元のオブジェクトはChild1だが使える機能はParentのもの Child1 c1 = (Child1)p1; //上記変数の元のオブジェクトはChild1なのでChild1でキャストが可能。オブジェクトは同じ物をさしている。 c1.DEF(); // Child2 c2 = (Child2)p1; // これは実行時にキャストでエラー。親子関係ではないのでNG。キャストしたからといって子クラス1のオブジェクトに子クラス2の機能が追加されるわけではない。 // パターンB Parent c3 = new Child1( new Child2( new Parent() ) );//コンストラクタ引数にChild2でラップ(?)しているわけではなく、Parent型の引数を渡しているだけ。 // Child2 c4 = (Child2)c3; // これも実行時にキャストでエラー。c3にChild2の機能が追加されているわけではない。 } } [ メッセージ編集済み 編集者: maru 編集日時 2003-03-22 13:37 ] | ||||||||||||
|
投稿日時: 2003-03-23 18:05
>OutputStream と BufferedOutputStream と DataOutputStream は、おそらく以下の
>ソースのような関係になると思います。 デザインパターンの1つ、Decoratorパターンですね。 デザインパターンの本をみると、必ずjava.ioが具体例として紹介されてます。 >※逆コンパイルしたわけではないのでわかりませんが・・・。 JDKのインストール時に選択しておけば、ルートディレクトリに"src.zip(or src.jar)" があります、解凍すればJavaAPIの全ソースが見れます。逆コンパイルする必要は... ありません。 [ メッセージ編集済み 編集者: asip 編集日時 2003-03-23 18:22 ] | ||||||||||||
|
投稿日時: 2003-03-24 10:46
こんにちは。
>デザインパターンの1つ、Decoratorパターンですね。 そうなんですか。デザインパターンって言葉は最近よく見かけますが、どんな物かよく知ら なかったり、フレームワークとごっちゃになってたりで興味ありませんでした。 そろそろJavaにもなれてきたので、ここらへんも勉強してみます。(^^) | ||||||||||||
1
