• 締切済み

java.util.Listのヒープサイズの取得

オブジェクトのサイズを取得するメソッドとして、  java.lang.instrument.Instrumentation#getObjectSize があることは教わったのですが、なんと、このメソッドは参照先オブジェクトの サイズを調べてくれません。 ですから、私の環境では、Listに何のオブジェクトをaddしても、しなくても 24 が返ってくるだけでした。 どなたか、List内のオブジェクトの合計のヒープサイズを求めるライブラリもしくは、 リフレクションとInstrumentation#getObjectSizeを使った合計のヒープサイズを調べる 具体的な実装例をご存知の方はおられませんでしょうか? ( 前の質問は全く無関係な方向に進んでしまっていますので、   しばらく放置させていただきます。ご了承ください。)

  • Java
  • 回答数9
  • ありがとう数1

みんなの回答

  • ssr-y6
  • ベストアンサー率71% (5/7)
回答No.9

以前、Listを使ったバッファのようなものを作らなければならなくなったときに、 使用メモリ量を概算で求めなければならくなり、そのときは以下のような方法でそれを求めました。 import java.lang.instrument.*; import java.util.*; class agent { public static Instrumentation Inst; public static void premain(String aargs, Instrumentation ins) { Inst = ins; }; } class getaboutobjectsize extends Object { public getaboutobjectsize() { super(); }; public long GetAboutObjectSize() { return(agent.Inst.getObjectSize(this)); }; } class StringGAOS extends getaboutobjectsize { private String Str; public StringGAOS(String str) { Str = new String(str); }; public long GetAboutObjectSize() { return(agent.Inst.getObjectSize(this) + new Integer(Str.length()).longValue() * 2 + agent.Inst.getObjectSize(Str)); }; } class IntegerGAOS extends getaboutobjectsize { private Integer Int; public IntegerGAOS(Integer num) { Int = new Integer(num); }; public long GetAboutObjectSize() { return(agent.Inst.getObjectSize(this) + agent.Inst.getObjectSize(Int)); }; } class StrIntGAOS extends getaboutobjectsize { public IntegerGAOS Int; public StringGAOS Str; public StrIntGAOS(String str, int num) { Int = new IntegerGAOS(num); Str = new StringGAOS(str); }; public long GetAboutObjectSize() { return(agent.Inst.getObjectSize(this) + Str.GetAboutObjectSize() + Int.GetAboutObjectSize()); }; } class ListGAOS extends AbstractList { public static final int MaxLineNumber = 100; private getaboutobjectsize Line[]; public ListGAOS() { int Int1; Line = new getaboutobjectsize[MaxLineNumber]; for (Int1 = 0; Int1 < MaxLineNumber; Int1 ++) Line[Int1] = new getaboutobjectsize(); }; public Object get(int index) {return(Line[index]); }; public int size() { return(MaxLineNumber); }; public void SetLine(int index, getaboutobjectsize item) { Line[index] = item; }; public void RemoveLine(int index) { Line[index] = new getaboutobjectsize(); }; public long GetAboutObjectSize() { long Long1 = 0l; int Int1; for (Int1 = 0; Int1 < MaxLineNumber; Int1 ++) Long1 += Line[Int1].GetAboutObjectSize() + agent.Inst.getObjectSize(Line[Int1]); return(Long1 + agent.Inst.getObjectSize(this)); }; } public class sizeoflist { public static void main(String args[]) { ListGAOS BufferList = new ListGAOS(); BufferList.SetLine(0, new StringGAOS("0123456789")); BufferList.SetLine(1, new IntegerGAOS(100)); BufferList.SetLine(2, new StrIntGAOS("abcdefghijklmnopqrstuvwxyz", -1)); System.out.println(Long.toString(BufferList.GetAboutObjectSize())); BufferList.SetLine(3, new StringGAOS("ABCDEFGHIJKLMNOPQRSTUVWXYZ")); System.out.println(Long.toString(BufferList.GetAboutObjectSize())); BufferList.RemoveLine(0); System.out.println(Long.toString(BufferList.GetAboutObjectSize())); }; } オブジェクトの大きさやメモリ上でのアドレスを取得することは、 プログラミング言語においての基本的な機能のはずです。 よってこれらの機能は、全てのオブジェクトの基底クラスのObjectクラスに実装されているべきものだと思います。 しかし、これが実装されていない(実行時クラスは取得できるのに)ということは、 Javaの言語仕様的にこれらの行為を『積極的』に『拒絶』していると考えられます。 もしこのような機能を使いたいのであれば、 使う方の『責任』で全て『手動』で実装しなければならないということです。

回答No.8

>テキストエディタの例で言うなら、文字列データそのものはどこにあるのでしょうか? >イメージエディタなら、そのラスタデータはどこにあるのでしょうか?これを含んでUndoバッファです。 自分が提案する方法は文字列データの場所を変えるということではありません。 もう一度具体的にご説明します。文字入力を表現するクラス class CharInput{   int index;   char data;   CharInput(int index, char data){     this.index = index;     this.data = data;   } } があって、一文字入力したときに undoBuffer.add(new CharInput(cursorPosition, data)); としてデータを保持しているとしましょう。でもCharInputのサイズを取得するのは厄介ですから、 undoBuffer.add(new byte[]{charInputTypeCode, cursorPosition, (byte)data}); のようにバイト列で保持すればいい、というだけの話です。 単にデータの保持の方法を変えてサイズが判るようにしているだけです。 必ずしもUndoバッファにそれらのデータが含める必要はありません。 やや話がそれているのですが、もしかして一回分のUndoのデータに その場面のデータを丸ごと記録しようとしていませんか?上記の例で言えば undoBuffer.add(textbox.getText()); とやるイメージです。これでもUndoは可能ですが、それは大量のメモリを消費しますよ? どうしてもその場面でのデータを丸ごと保持したいのであれば、 これまでの回答でお答えしたとおり文字列データなりラスタデータなりをシリアライズして 保持するだけですから、前述の方法でやり方はとくに変わりません。 >どこにあるのでしょうか? ということに関しては、テキストエディタならテキストボックスには保持されているということになりますし、 それがなくてもUndoバッファを辿ればいつでも最新の状態を再び構築できます。 >例えば、エディタのテクストがフォント名を持っているかもしれない(またはnullかも知れない), >フォント色を持っているかもしれない(〃),バックグラウンドのテクスチャパターンを持ているかも知れない(〃) >等を考えてみてください。 その場合も自分にはとくに問題があるようにはみえませんが……? 文字の入力や削除を表現するデータに加えて、フォントの変更の操作を表現するUndoデータを持つだけです。 どこが問題なのでしょう?自分の説明がうまく伝わっていないのでしょうか。 >UndoManagerがUndoableEditのオブジェクト構造を予め全てを知っていなくてはいけないよう実装なら、 >オブジェクト指向言語での設計の利点は殆どなくなるでしょう。 前述のとおり、自分がこのトピックで提案した方法では、データの保持の方法が変わるだけなので 「UndoManagerがUndoableEditのオブジェクト構造を予め全てを知っていなくてはいけないよう実装」に する必要はありませんよ。 また、さらに話がそれるのですが、オブジェクト指向言語の設計の利点は実装の隠蔽だけではないことを指摘しておきます。

回答No.7

>文書全体の2/3を削除したとしましょう。 >この場合、削除した2/3の情報を保持するよりも、 >残った1/3を保持するほうが効率のよいことは簡単にわかります。 (2/3) > (1/3) ということは「オブジェクトのサイズ」を知らなくてもわかりますよね? そこでなぜさらに「オブジェクトのサイズ」が必要だと考えておられるのかわかりません。 また「残った1/3」はUndoが出来ないアプリケーションだとしても必要な情報ですから、 「削除した2/3の情報」のどちらが効率がよいかという比較をする意味がよくわかりません。 質問者のかたは「削除した2/3の情報」および「残った1/3の情報」とは 具体的にどのような情報を想定していますか? 自分もごく単純で具体的な例で考えてみます。 テキストエディタで文書全体の一部を削除する操作の場合、 操作を表現するのに必要な最小の情報は、 ・削除の操作であることをしめす値 ・削除された範囲の開始位置 ・削除された範囲の終了位置 になりますので、これを単純にシリアライズします。 すべてintにしてしまいました。 ByteArrayOutputStream buffer = new ByteArrayOutputStream(); DataOutputStream stream = new DataOutputStream(buffer); stream.writeInt(operationType); stream.writeInt(startPosition); stream.writeInt(endPosition); byte[] data = buffer.toByteArray(); ここで data.length は 12 になります。 これでこのデータのサイズは12バイトと判り、これを読み取ればUndo/Redoもできるわけです。 (もし削除した文字列も保持していた場合、Redo/Redoデータはその分サイズが大きくなりますが、 そのかわりにそれまでの操作履歴を辿らなくてもUndoができるので高速化がはかれます) ここで、 >削除した2/3の情報を保持するよりも、残った1/3を保持するほうが効率のよい というような選択が生じるようには見えないのですが……? >Javaでも、プロファイラ等のツールは、オブジェクトのサイズを知っています そもそも、Javaには強いセキュリティがあるので、 privateなフィールドへのアクセスはリフレクションを持ってしてもできません。 従ってあるオブジェクトがフィールドに持つすべての参照をたどり、 その先にあるオブジェクトのサイズすべてを計測することはできません。 C言語のsizeofでもポインタの先のデータのサイズまでは含めません。 >それをあいまいにしたまま、誰もがUndoバッファを実装ているとはとても思えません。 自分はUndo/Redoのデータをbyte[]で保持していれば、 「参照先オブジェクトのサイズを含む、オブジェクトのサイズ」を計測する方法がなくても、 配列のlengthフィールドを参照するだけでサイズが測れると思うのです。 C言語のようなメモリが丸出しの言語であれば独自のメモリ管理を実装できるでしょう。 それは質問者さんのイメージには近いでしょうけれど、 それは安全に欠けるし上で挙げた方法より特別優れているとは思いません。 そうこう考えているうちに、ほかにふたつばかり荒業が思いつきました。 要はUndo/Redoのデータだけ別のメモリ空間に確保できればいいわけですね。 ひとつはネイティブに独自のメモリ管理が出来る仕組みを作り、 そこにJNIでRedo/Undoのデータを書き込む方法。 もうひとつの方法は、もうひとつVirtual Machineを起動して、そっちのヒープにUndo/Redoのデータを格納してしまうとか……。 どっちもさすがにバカバカしいですけれど。

ggable
質問者

補足

>ここで data.length は 12 になります。 >これでこのデータのサイズは12バイトと判り、これを読み取ればUndo/Redoもできるわけです。 具体的に、Undoバッファを実装された経験をお持ちでしょうか? テキストエディタの例で言うなら、文字列データそのものはどこにあるのでしょうか? イメージエディタなら、そのラスタデータはどこにあるのでしょうか?これを含んでUndoバッファです。 >「参照先オブジェクトのサイズを含む、オブジェクトのサイズ」を計測する方法がなくても、 >配列のlengthフィールドを参照するだけでサイズが測れると思うのです。 例えば、エディタのテクストがフォント名を持っているかもしれない(またはnullかも知れない), フォント色を持っているかもしれない(〃),バックグラウンドのテクスチャパターンを持ているかも知れない(〃) 等を考えてみてください。 UndoManagerがUndoableEditのオブジェクト構造を予め全てを知っていなくてはいけないよう実装なら、 オブジェクト指向言語での設計の利点は殆どなくなるでしょう。

回答No.6

>前の質問は全く無関係な方向に進んでしまっています 申し訳ないです。このトピックにおいては具体的な解決策に限って検討してみます。 >このメソッドは参照先オブジェクトのサイズを調べてくれません そうですね。参照先のオブジェクトはサイズを測るオブジェクトの「外」にあるからですね。 これらの流れを見た限りでは、そもそも目的は「オブジェクトのサイズの取得」ではなく 「バッファのサイズを指定できる無限Undo」のようですから、 手段のひとつにすぎない「オブジェクトのサイズの取得」に限る必要はないようにみえます。 自分なら、Undo/Redoの情報を持つオブジェクトをオンメモリにシリアライズする方法が思いつきます。 java.io.ByteArrayOutputStreamか何かにUndo/Redo一回分のデータを書き込んでしまいます。 そうすれば一回分のサイズを取得できますから、 これを合計すればUndo/Redoで使っているメモリを概算できます。 そもそも、メモリに乗らなかった分は結局シリアライズしてファイルに保存することになるのですから、 コーディングの手間としてはそれほど余計な負担にならないように思います。 ただし、これはシリアライズ/デシリアライズにかかるコストを無視できる場合に限ります。 すばやくデシリアライズできないとUndoボタンの反応が悪くなりそうなので、 実際に実装して使い勝手を試してみるのがいいでしょう。 また、前後のUndo/Redoデータが同じデータを共有していた場合は、 それを別々にシリアライズするとメモリを余分に必要になるかと思います。 Javaにもとから用意されているシリアライズ機構を利用すればコーディングの手間はある程度抑えられますが、 Undo/Redoに使うにはかなり重いですし、オブジェクトをそのままヒープに持っておくのに比べて メモリ効率がいいかはわかりませんので、自前でシリアライズを書くのも考えたほうがよさそうです。 場合によっては、最初からどんどんファイルに書いていってしまうのもいいかも知れません。 Undo/Redoをするたびにファイルアクセスが発生するわけですが、 アプリケーションの種類によってはそれでも十分だったりしますし、使用メモリが少なくなりますから。 というわけで、Undo/Redoのオブジェクトをオンメモリでシリアライズする方法、 検討してみてはいかがでしょうか。

参考URL:
http://java.sun.com/javase/ja/6/docs/ja/technotes/guides/serialization/index.html
ggable
質問者

補足

ご回答ありがとうございます。 しかしながら、問題は直列化の前にあります。 たとえば簡単な例として、テキストエディタを考えて見ます。 文書全体の2/3を削除したとしましょう。 この場合、削除した2/3の情報を保持するよりも、 残った1/3を保持するほうが効率のよいことは簡単にわかります。 ところが、オブジェクトのサイズがわからないと、これが判断できません。 Javaでも、プロファイラ等のツールは、オブジェクトのサイズを知っていますし、 それをあいまいにしたまま、誰もがUndoバッファを実装ているとは とても思えません。 どなたか、実用的・具体的な実装例をご存じないでしょうか?

  • _ranco_
  • ベストアンサー率58% (126/214)
回答No.5

> 無限Undoが必要なアプリケーションの > Undoバッファ コンピュータは有限マシンなので無限はありえませんが、基本的にはディスクアクセスによりオンメモリのデータを入れ替えていきます(Undoバッファの全体100%が常時オンメモリにある必要はない)。オンメモリのデータは、ユーザの操作に伴って徐々に肥大していきますから、「オブジェクトのヒープサイズの取得」のスレッドで述べたような技法によりメモリ使用状況をチェックし、そろそろヤバイ状況のときには比較的古い部分を解放(すでにディスク上にあるものなら単純に解放、そうでなければディスクに書き込んでから解放)して、JVMの空きメモリを増やしてやります。 でも実際には、メモリ数ギガバイトの今日の時代では(*)、運用時にディスクアクセスをまったくしない(完全オンメモリ)のデータベースも登場しているぐらいですから、Undoバッファをオブジェクトの参照のLinkedList等とするなら、必要に応じて画像データだけをディスクから読み込む方式で、十分な実用性を実現できると思います(Undo情報そのものは完全に100%オンメモリにできる)。PhotoShopやGIMPのような画像アプリケーションは、すでにその方式のようです(ソースを見てませんが、使った感じとして)。 (*:JVMの-Xmxも、今では2Gb~4Gbを指定可能。)

  • _ranco_
  • ベストアンサー率58% (126/214)
回答No.4

> 無限Undoが必要なアプリケーションの > Undoバッファ コンピュータは有限マシンなので無限はありえませんが、基本的にはディスクアクセスによりオンメモリのデータを入れ替えていきます(Undoバッファの全体100%が常時オンメモリにある必要はない)。オンメモリのデータがUndoバッファの先頭部分だったときは、徐々に肥大していきますから、「オブジェクトのヒープサイズの取得」のスレッドで述べたような技法によりメモリ使用状況をチェックし、そろそろヤバイ状況のときには比較的古い部分を解放(すでにディスク上にあるものなら単純に解放、そうでなければディスクに書き込んでから解放)して、JVMの空きメモリを増やしてやります。 でも実際には、メモリ数ギガバイトの今日の時代では(*)、運用時にディスクアクセスをまったくしない(完全オンメモリ)のデータベースも登場しているぐらいですから、Undoバッファをオブジェクトの参照のLinkedList等とするなら、必要に応じて画像データだけをディスクから読み込む方式で、十分な実用性を実現できると思います(Undo情報そのものは完全に100%オンメモリにできる)。PhotoShopやGIMPのような画像アプリケーションは、すでにその方式のようです(ソースを見てませんが、使った感じとして)。 (*:JVMの-Xmxも、今では2Gb~4Gbを指定可能。)

ggable
質問者

補足

>コンピュータは有限マシンなので無限はありえませんが、 無限Undoの意味すらわからない人の回答らしく支離滅裂です。 >メモリ使用状況をチェックし、そろそろヤバイ状況のときには比較的古い部分を解放 >メモリ数ギガバイトの今日の時代では ”そろそろヤバイ”って何ですか? メモリが何GBあろうとも、有限である限り原理的には全く同じです。 freeMemoryとオブジェクトサイズを比較するからこそ、”そろそろヤバイ”か どうかが判断できるのでしょう。 >PhotoShopやGIMPのような画像アプリケーションは、 >すでにその方式のようです(ソースを見てませんが、使った感じとして)。 適当な思いつきの回答は必要としていません。 一般的なアプリは当然Undoバッファのサイズを制御してますから。 もう、あなたからの回答に対する返信は二度としません。

  • _ranco_
  • ベストアンサー率58% (126/214)
回答No.3

>(Runtime#totalMemory()と、Runtime#freeMemory()を > 利用している方法です。) ですから、筆者(Vlad Rob氏)が類似記事(これはたいへんな労作!): http://www.javaworld.com/javaworld/javaqa/2003-12/02-qa-1226-sizeof.html?page=1 で断っているように、利用状況に制約があり(hirusagari説と同様)、かつ、オブジェクトのサイズの近似値としても限界があります。 Javaにsizeof()がないのは、Javaではプログラマがメモリアロケーションを物理的に制御できないため。だから、オブジェクトのアロケーションの直後にfreeMemory()ががくっと減れば、それをサイズの見当にするぐらいで十分です。オブジェクトのサイズにこだわるのは、Javaでポインタを使いたい!とこだわるのに似ている。つまり、せっかくの高レベル言語(プログラマにいろいろ楽をさせてくれる)を、Cなみの低レベル言語として使おうとしている。無駄で、無意味なことです。

ggable
質問者

補足

>無駄で、無意味なことです。 では、CADソフトのように無限Undoが必要なアプリケーションの Undoバッファは、Javaでは具体的にどのようにして実装するんですか?

  • yuji
  • ベストアンサー率37% (64/169)
回答No.2

参考URLの方法で調査してみてはどうでしょうか? (Runtime#totalMemory()と、Runtime#freeMemory()を  利用している方法です。)

参考URL:
http://www.javaworld.com/javaworld/javatips/jw-javatip130.html
  • _ranco_
  • ベストアンサー率58% (126/214)
回答No.1

Javaには、オブジェクトのサイズを知る方法は提供されていません。それは、昔からのJava常識の一つです。それにまた、プログラマにとって、オブジェクトのサイズを知る必要性もまったくありません。ランタイムのメモリチェック~メモリ管理のためには、Runtime.freeMemory()を使うのが標準的な方法です。このメソッドが返す値も、概略の値ですが。 > 前の質問は全く無関係な方向に進んでしまっていますので、 とほほ。とんでもないご感想を!。

関連するQ&A

  • オブジェクトのヒープサイズの取得

    任意のオブジェクトの実行中のヒープサイズを取得する方法を教えてください。 具体的には、Undoバッファ(LinkedList)を実装していて、そのヒープサイズが あるサイズを超えた場合には、HDDに内容を保存してヒープを開放したいと考えています。 これを実現するために、動的にヒープサイズを取得する必要があるのですが、 また、上記のようにListがあるサイズを超えたら自動的にHDDなどに保存・呼び出しをしてくれて ユーザレベルでオンメモリがどうか等を意識しなくてもすむようなライブラリは 存在しないでしょうか? 以上2点について、よろしくお願いします。

  • ヒープサイズの限界

    javaで 2.modPow(100000000, 1000); 2の100000000乗のmod1000を計算しようとしたらjava.lang.OutOfMemoryError: Java heap spaceとヒープサイズが限界のようでエラーがでます。 実行するときに-Xmx1400mがサイズを大きくできる限界のようでこれ以上大きくすることができません。 この計算をするのは物理的に無理なんでしょうか? 自分のパソコンのメモリは3.42Gです。

    • ベストアンサー
    • Java
  • Java リフレクションについて

    1.リフレクションを使い、値をセット(BeanのSetterメソッドにて) 2.1でセットした値を取得するために、下記コードで取得 Method Method = Class.getMethod("getLstData"); Object obj = Method.invoke(****); 上記の****の箇所には、メソッドのあるクラスのインスタンスを渡す、 というところまでは分かりますが、newInstance()してしまうと、新しいオブジェクトになってしまうので 値が取得できません。 error>>java.lang.IllegalArgumentException: object is not an instance of declaring class どのようにすれば、値の取得が可能でしょうか。 どなたかご教授いただければと思います。 ※Java 1.5を使用

    • ベストアンサー
    • Java
  • リフレクション

    Webアプリ上でリフレクションにてとあるクラスのメソッドを実行するサンプルを作成して 見たのですがうまく動きませんでした。最後のmethod.invoke()の処理にてExceptionが発生し、 java.lang.IllegalArgumentException: object is not an instance of declaring class と表示されてしまいます。 作成したサンプルは下記なのですがどこが原因かお分かりになりますでしょうか。 try { Class cls = Class.forName("dao.TestDao"); // 引数の型をセット Constructor constructor = cls.getDeclaredConstructor(HttpSession.class); constructor.setAccessible(true); // 引数を渡してオブジェクトを生成 Object obj = constructor.newInstance(session); Method method = cls.getDeclaredMethod("getDataDao", int.class); method.setAccessible(true); Object result = method.invoke(cls, new Integer(100)); } catch (Exception e) { e.printStackTrace(); } // このクラスのgetDataDao()をリフレクションにて実行 public class TestDao { HttpSession session = null; public TestDao(HttpSession session) { this.session = session; } public List<String> getDataDao(int iNo) { List<String> list = new ArrayList<String>(); list.add((String)session.getAttribute("1")); list.add((String)session.getAttribute("2")); list.add((String)session.getAttribute("3")); list.add((String)session.getAttribute("4")); list.add((String)session.getAttribute("5")); return list; } }

    • ベストアンサー
    • Java
  • javaのプログラミングについての質問です。

    Javaのプログラムについての質問です。長くなってしまいますがご容赦下さい。 Listインターフェースの実装クラスの自作と、作成したクラスの全メソッドを呼び出すサンプルを作成せよ、という問題です。以下が現在までに作成したコードになります。 注意点として、java.util.Listの実装クラスは使用出来ません(ArrayListなど)。実装するメソッドは、コードの中にコメントを振ってあります。 import java.util.List; import java.util.Collection; import java.util.Iterator; import java.util.ListIterator; class Mylist implements List{   private int Count;   private String Data[];   // コンストラクタ   public Mylist(){    Data = new String[10];    Count = 0;   } /** 実装するaddメソッド @return boolean APIの設定に従う @param e エレメント(要素) **/   public boolean add(E e){    Data[Count] = (String)e;   Count++;   return true;   }   public void add(int i,Object str){   }   public boolean addAll(Collection c){     return false;   }   public boolean addAll(int i,Collection c){     return false;   } /** 実装するclearメソッド **/   public void clear(){     Count = 0;   }   public boolean contains(Object str){     return false;   }   public boolean containsAll(Collection c){     return false;   }   public boolean equals(Object str){     return false;   } /** 実装するgetメソッド @return E エレメント(要素) @param i 指定されたインデックス番号 **/   public E get(int i){      /*     エレメントeに、String型Data[i]を     キャストして格納*/     E e = (E)Data[i];     return e;   }   public int hashCode(){     return -1;   }   public int indexOf(Object str){     return -1;   }   public boolean isEmpty(){     return false;   }   public Iterator iterator(){     return null;   }   public int lastIndexOf(Object str){     return -1;   }   public ListIterator listIterator(){     return null;   }   public ListIterator listIterator(int i){     return null;   }    /**   * 実装するremoveメソッド   * @return E エレメント(要素)   * @param index 指定されたインデックス番号   **/   public E remove(int index){ /* Dataを最大まで回し、iをインクリメントしたData[i++]を String型Dataに格納する*/ for(int i = index; i < Data.length; i++){ Data[i] = Data[index++]; } Count--; E e = (E)Data; return e; } public boolean remove(Object str){ return false; } public boolean removeAll(Collection c){ return false; } public boolean retainAll(Collection c){ return false; } /** * 実装するsetメソッド * @return E エレメント(要素) * @param i 指定されたインデックス番号 * @param element 置き換える要素 **/ public E set(int i,E element){ // String型Dataにelementをキャストして格納 Data[i] = (String)element; // エレメントeにData[i]をキャストして格納 E e = (E)Data[i]; // 値を返す return e; } /** * 実装するsizeメソッド * @return int 指定されたインデックス番号 **/ public int size(){ return Count; } public List subList(int i,int j){ return this; } public Object[] toArray(){ return Data; } public Object[] toArray(Object[] a){ return Data; } } class Main { /** メインメソッド **/ public static void main(String args[]) { Mylist sub = new Mylist(); /* addメソッドを実装し、機体名を要素とする。 addを最大まで回し、getメソッドで要素を取り出して表示する*/ sub.add("ビルドバーニングガンダム"); sub.add("ライトニングガンダム"); sub.add("ウイニングガンダム"); sub.add("ガンダムフェニーチェリナーシタ"); sub.add("R・ギャギャ"); sub.add("ユニコーンガンダム"); for(int i = 0; i < sub.size(); i++){ System.out.println(sub.get(i)); } // sizeメソッド System.out.println("\r\n" + "機体数は" + sub.size() + "です" + "\r\n"); // setメソッド sub.set(0,"ガンダムエピオン"); for(int i = 0; i < sub.size(); i++){ System.out.println(sub.get(i)); } // 改行 System.out.println(); // removeメソッド sub.remove(1); for(int i = 0; i < sub.size(); i++){ System.out.println(sub.get(i)); } // clearメソッド sub.clear(); System.out.println("\r\n" + "機体数が" + sub.size() + "になったので負けです"); } } コンパイルして実行すると、removeメソッドで指定した箇所ではなく、要素の1番最後が削除されています。思うに、removeメソッドを実装する所のfor(int i = index; i < Data.length; i++){の中の条件が違うと思うのですが。。。。 また、現在addには10個箱を作成するようにしていますが、11個目をメインクラス内で用意した場合、例外ではなく新たに箱を作らなければならない、という後だしジャンケン的な事を言われて、思わず「じゃあArrayListでいいじゃないか」と思ってしまいました。 気を取り直してこの3連休で終わらせたいと思っています。ここまでで現状コードの完成は50%かそれ以下だとは思いますが、どなたか上記2点について御教授頂けないでしょうか。よろしくお願い致します。

  • Javaのプログラムの質問です。

    Javaのプログラムについての質問です。 Listインターフェースの実装クラスの自作と、作成したクラスの全メソッドを呼び出すサンプルを作成せよ、という問題です。  注意点として、java.util.Listの実装クラスは使用出来ません(ArrayListなど)。実装するメソッドは、コードの中に番号を振ってあります。 import java.util.Collection; import java.util.Iterator; import java.util.ListIterator; import java.util.List; class LocalList implements List{  private int Count;  private String Data[];  private Iterator ite;  private ListIterator lite;  // コンストラクタ  void mylist(){   Data = new String[10];   Count = 0;  }  (1)  public boolean add(Object str){   if(Count >= 10){    return false;   }   Data[Count ++] = new String((String)str);   return true;  }  public void add(int i,Object str){  }        public boolean addAll(Collection c){   return false;  }        public boolean addAll(int i,Collection c){   return false;  }    (2)  public void clear(){   Count = 0;  }  public boolean contains(Object str){   return false;  }          public boolean containsAll(Collection c){   return false;  }  public boolean equals(Object str){   return false;  }    (3)  public Object get(int i){   return (i >= Count);  }  public int hashCode(){   return -1;  }  public int indexOf(Object str){   return -1;  }  public boolean isEmpty(){   return false;  }  public Iterator iterator(){   return ite;  }     public int lastIndexOf(Object str){   return -1;  }     public ListIterator listIterator(){   return lite;  }     public ListIterator listIterator(int i){   return lite;  }    (4)  public Object remove(int i){   return (i >= Count);  }    public boolean remove(Object str){   return true;  }         public boolean removeAll(Collection c){   return false;  }         public boolean retainAll(Collection c){   return false;  }    (5)  public Object set(int i,Object str){   return Data[i];  }    (6)  public int size(){   return Count;  }  public List subList(int i,int j){   return this;  }  public Object[] toArray(){   return Data;  }  public Object[] toArray(Object[] a){   return Data;  } } class Main {  public static void main(String[] args) {   mylist sub = new mylist();   sub.add("ビルドバーニングガンダム");   sub.add("ライトニングガンダム");   sub.add("ウイニングガンダム");   sub.add("ガンダムフェニーチェリナーシタ");   sub.add("R・ギャギャ");   for(int i = 0; i < sub.size(); i++){      System.out.println(sub.get(i));   }   // 改行   System.out.println();   // setメソッド   sub.set(1,"ガンダムエピオン");   for(int i = 0; i < sub.size(); i++){    System.out.println(sub.get(i));   }   // 改行   System.out.println();   // sizeメソッド   System.out.println("\r\n" + "機体数は" + sub.size() + "です" + "\r\n");   // removeメソッド   sub.remove(1);   for(int i = 0; i < sub.size(); i++){       System.out.println(sub.get(i));   }   // clearメソッド   sub.clear();   System.out.println("\r\n" + "機体数が" + sub.size() + "になったので負けです");    } } setメソッドとremoveメソッド以外は起動するのようになったのですが、この2つがうんともすんとも動きません。ジェネリクス型を使うという考え方もあるらしいのですが、ネットで調べてもピンと来ず寸詰まり状態になってしまっています。後少しだと思うのですが。。。。 どなたかご教授頂けないでしょうか?よろしくお願い致します。

  • Javaのプログラムについての質問です。

    Listインターフェースの実装クラスの自作と、作成したクラスの全メソッドを呼び出すサンプルを作成せよ、という問題です。 注意点として、java.util.Listの実装クラスは使用出来ません(ArrayListなど)。 以下は極最初期のソースになります。 import java.util.List;  public interface Interface{   int size();   boolean add();   boolean remove();   void clear();   get();   set();  } public class LocalList implements Interface{ class Main implements LocalList {  public static void main(String[] args) {     } } Listインターフェースについてネットで調べてはいるのですが、具体的な解決方法が見えてきません。 どなたか参考ソースや考え方などを教えていただけないでしょうか。よろしくお願い致します。

  • リフレクション

    リフレクションによって、Stringの値(strVal)を各クラスのオブジェクトに変換したいと思っております。 下のようなコードで、this.typeにセットしてあるオブジェクトのvalueOfメソッドを実行したいのですが、clazz.getMethod部分で次のようなExceptionが発生してしまいます。 staticメソッドはgetMethodでは取得・実行できないのでしょうか? ご存知の方いらっしゃいましたら、教えて頂けないでしょうか。 【Exception】 java.lang.NoSuchMethodException: java.lang.String.valueOf() 【コード】 Class clazz = Class.forName(this.type); Method method = clazz.getMethod("valueOf", new Class[0]); return method.invoke(clazz.newInstance(), new Object[]{strVal} ); 今回、this.typeには、"java.lang.String"が入っています。

    • ベストアンサー
    • Java
  • VC++/MFCでリフレクション

    Javaでは、ObjectのgetClass()でClassクラスの インスタンスが取れ、実行時に指定した、メソッド名や、引数で、動的にメソッドを呼びだすようなリフレクション機能が使用できます。 同様のことをC#でも実装したことがあります。 VC++/MFCにて、このようなリフレクションをやるやり方を教えてください。 C++の標準あるいわ、MFCの機能など、どちらでもよいです。 メタクラス型のようなものを実行時に取得して、リフレクションする方法だと思います。 質問の内容はVC++.NETやVC++/CLIではないです。そちらのほうでのやり方は既に発見しました。

  • 最大ヒープサイズに対して、JMVのメモリサイズがありえない程小さいです

    Javaとeclipseを使い始めてまだ2週間程度ですが、よろしくお願いします。 ある簡単なテストプログラムで Exception in thread "main" java.lang.OutOfMemoryError: Java heap space が出ましたので、java.lang.Runtime のメソッドを使って、JVMのメモリサイズを調べてみました。 JVM内の空きメモリを調べる freeMemory() メソッドを随所に入れると、確かにある箇所から激減したので、リークしてるらしきところは発見できました。ただ、JVMメモリの総容量を出力する totalMemory() を入れてみると、プログラム開始直後から、この値が5177344しかありません。API仕様によればbyte単位だそうなので、初めからJVMには4.9MB程度しか割り当てられていないということなのでしょうか。以下に示すように、eclipseで設定している最大ヒープサイズは、512MBにしています。(これ以上大きくとると、eclipseの起動エラーになりました。原因はわかりません。) 実行環境はWindowsXP(メモリ1GB)で、Windowsのタスクマネージャのパフォーマンスタブに表示される利用可能な物理メモリは、350MB~400MBくらいです。この環境でこれだけのJVMサイズしか取られない原因は、何が考えられるでしょうか?あるいは、どこかの設定が間違っていますでしょうか? eclipse.iniの内容は、以下の通りです。 -startup plugins/org.eclipse.equinox.launcher_1.0.201.R35x_v20090715.jar --launcher.library plugins/org.eclipse.equinox.launcher.win32.win32.x86_1.0.200.v20090519 -product org.eclipse.epp.package.jee.product --launcher.XXMaxPermSize 256M -showsplash org.eclipse.platform --launcher.XXMaxPermSize 256m -vmargs -Dosgi.requiredJavaVersion=1.5 -Xms40m -Xmx512m

    • ベストアンサー
    • Java

専門家に質問してみよう