ArrayListに異なる型のオブジェクトを格納する際のエラーについて

このQ&Aのポイント
  • こんにちは。ArrayListに異なる型のオブジェクトを格納しようとしている際にエラーが発生しています。具体的には、オブジェクトを格納したArrayListから要素を取り出そうとする際に型キャストのエラーが発生しています。
  • このエラーが発生する原因は、ArrayListはジェネリックではないので、内部的にはすべての要素がObject型として扱われるためです。そのため、格納されたオブジェクトを取り出す際には明示的な型キャストが必要となります。
  • しかし、オブジェクトの実際の型を事前に知ることができない場合や、誤った型でキャストしようとした場合には、型キャストのエラーが発生します。この場合、正しい型のオブジェクトが格納されているかどうか事前に確認する必要があります。
回答を見る
  • ベストアンサー

VC#2010 ArrayListに入れた要素の型

こんにちは。ArrayListに異なる型のクラスを入れて、後からそれがどの型か判断してから処理しようとしているのですが、エラーになってしまいます。 //ベースオブジェクトクラス class BaseObj { string path; BaseObj(string p){path = p:} } //製品Aクラス BaseObjを継承 class ProductA : BaseObj { ProductA(string p) : base(p) {} } //製品Bクラス BaseObjを継承 class ProductB : BaseObj { ProductB(string p) : base(p) {} } ------------------------------------------- ArrayList ObjList;//オブジェクトを格納する ProductA A = new ProductA(@"C:\"); ProductB B = new ProductB(@"D:\"); ObjList.Add(A); ObjList.Add(B); ------------------------------------------- //ここでは、0番目にAが入ってると分かっているのでAかBか調べる処理は省いてます。 MessageBox.Show'((ProductA)ObjList[0]).path); 上記メッセージボックスのところで、 型 'System.Collections.Generic.List`1[Application.ProductA]' のオブジェクトを型 'Application.ProductA' にキャストできません。 というエラーになってしまいます。これはどうしてなのでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
noname#251971
noname#251971
回答No.2

エラーメッセージを見る限り、 実際のソースコードと質問文に記載されているコードで大きく差があり、 実際には ObjList[0] には ProductA ではなく、 List<ProductA> 型のオブジェクトが格納されているように見受けられます。 要素を Add() する箇所で、ProductA 型のオブジェクトを格納しているかを確認してみてください。 なお、ArrayList クラスはまだ.NETにジェネリックが導入される前、 .NET Framework 1.1 の時代に利用されていた古いクラスです。 現在ではジェネリックによる型付き(いわゆるタイプセーフ)な List コレクションが存在します。 質問文の例ですと、共通の基底クラスである BaseObj がありますので、 ArrayList の代わりに List<BaseObj> を利用することができるかと思います。 # List<BaseObj> には BaseObj を派生した ProductA や ProductB も格納できます。 型付きにすると何が良いかというと、 今回の例のように、誤った要素を入れてしまうコードを記述すると、 コンパイルを行う時点でエラーにしてくれます。 # ArrayList のばあい、すべて object 型で型情報が無くなってしまうので、 # 間違いがあるところまで実行してみないとわかりません。 今回の問題も、ひとまず ArrayList を List<BaseObj> に変えてみると 型が合わないオブジェクトを追加する箇所でコンパイルエラーが出るかと思いますので、 すぐに問題箇所が発見できるかと思われます。

coelacanth9
質問者

お礼

ご回答ありがとうございます。 仰るとおり、投稿したコードは間違えていました。そのままコピペするとごちゃごちゃするので簡略化しようとして間違えてしまいました・・・。 そして、教えていただいたようにListでやってみると間違いが分かりました。この例だと、ArrayListにProductAを追加しなくてはならないのに、List<ProductA>を追加してしまっていました。それでエラーコードの意味も分かりました。 分かりやすい説明をしていただき、ありがとうございました!今後はArrayListはやめて起きます。

その他の回答 (1)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

規格は追い切れてないんだけど, 見た感じ (ProductA) によるキャストが ObjList にしかかかっていないんじゃない?

coelacanth9
質問者

お礼

ご回答ありがとうございます。 僕の書いた内容が間違っていたのですが、Tacosanさんのおっしゃっている事もあたらずも遠からずという感じでした。今回はもう一方の回答者様の方で理解できましたので、そちらをベストアンサーにさせて頂きます。

関連するQ&A

  • arraylistの呼び出し

    A.classでB.classのarraylistを作成し Cクラスのオブジェクトを何個もarraylistに保存しているんですけど そのarraylistをbクラスで使いたいんですけど うまくいきません 例とエラー文を載せますので、教えてください 例 public class A{ int i=0; int b=0; public static void main(String[] args){ ArrayList<B> strs=new ArrayList<B>(0); for(b=0;b<30;b++){ B b =new B(); //ここは何回も作ってます strs.add(b,i);   i++; } } public ArrayList get(){ return strs; } } class C { A a; static count=0; public void syutoku(SimpleTrajectoryViewer si){ this.a=a; } public void c(){ B b=new B(); ArrayList b =a.get(); B p=b.get(count); count ++; } } エラー文はクラスの ArrayList b =a.get();の部分で 互換性のない型 期待値  B 検出値     object と出ています 解決策教えてください 全てのプログラムを書いてるわけではありませんので おそらく関係のあるだろうってところを書きましたので わかりづらかったらすみません

  • ArrayListを改良したい

    visual C# 2010 Express を使用しています。 ArrayListは動的に要素を追加できるの便利なのですが、 次のような使い方で要素を取り出そうとするとasキャストが必要になってしまいます・・・ class Data : Dictionary<string, string> { } class DataList : ArrayList { public void Add(Data value) { base.Add(value as Data); } } class Program { static void Main(string[] args) { var d = new Data(); d["a"] = "aa"; d["b"] = "bb"; DataList arr = new DataList(); arr.Add(d); // var dd = arr[0] as Data; var dd = arr[0]; Console.WriteLine(dd["a"]);// エラー 角かっこ [] 付きインデックスを 'object' 型の式に適用することはできません。 Console.ReadLine(); } } そこでというか、ラップした独自のクラスを作りたいと思い上のような感じで作成したのですが、 やはり同じエラーになってしまいます・・・ asキャストを必要とせず、そのままDataクラス(Dictionary<string, string>)を 取り出すためにはどのように作成したら良いのでしょうか?

  • ArrayListのcloneメソッド

    お世話になります。 ArrayListのcloneメソッドなんですが、API上は「ArrayList のインスタンスのシャローコピーを返します。要素自体はコピーされません。 」と記載がありますが、 「ディープコピー」をしているような感じがして、なぜ「シャローコピー」と言っているのか、教えて欲しいです。 しかも、要素自体もコピーされているような…。 自分の理解では、 シャローコピー:コピー元、コピー先で同じオブジェクトを参照する ディープコピー:コピー元、コピー先で違うオブジェクトを参照する 試したソースは以下です。 --------------- import java.util.ArrayList; public class Test { public static void main(String[] args) { ArrayList<String> array = new ArrayList<String>(); array.add("a"); array.add("b"); ArrayList<String> array2 = (ArrayList<String>) array.clone(); array2.add("c"); System.out.println("array:" + array); System.out.println("array2:" + array2); } } --------------- cloneメソッドはシャローコピーなので、array2で「c」がaddされたら、arrayも「c」が追加されて、 array:[a, b, c] array2:[a, b, c] となるはずが、 array:[a, b] array2:[a, b, c] となります。 array、array2は別々のオブジェクトを参照しているような気がします。 恐らく大きな勘違いをしているのかもしれませんが、 調べてもいまいち理解できませんでした。 お手数おかけしますが、よろしくお願い致します。

    • ベストアンサー
    • Java
  • 「型 ArrayList は総称ではありません・・・。」エラーについての問題です。

    コンニチハ、javaの初心者s-unです。 Eclipse(Ver:3.1.1)でJavaのプログラムを書いています。 *********************************** import java.util.ArrayList; class collectionTest1{ public static void main(String args[]){ ArrayList<String> array = new ArrayList<String>(); } } *********************************** エラーメッセージは 「型 ArrayList は総称ではありません。引数 <String> でパラメーター化できません。」 JDK準拠>>コンパイラー準拠レベル5.0になっています。 原因をお教え頂けますと幸いです。 よろしくお願い申し上げます。

    • ベストアンサー
    • Java
  • ArrayListでの要素の取り出し

    Javaについて質問です。 名前順にソートしたArrayListのある要素だけを取り出して、 DefaultListModelに追加していきたいのですが、 book = new AddressBook(); book.add(new Address(太郎,住所,電話番号,メールアドレス)) book.add(new Address(花子,住所,電話番号,メールアドレス)) この例で、1番目の要素の名前だけ取り出すにはどうすればいいのでしょうか。 model.clear(); book.shellSort(); for(int i = 0; i < book.size(); i++){ String[] field = (String)book.get(i).split(",");//←ここでエラーになります。 model.addElement(field[0]); } ObjectとStringの扱いが分からず立往生です… 回答お待ちしております。

  • ArrayListなかへのArrayListオブジェクトのセット方法

    スケジュールのプログラムを作成していまして、1日分のオブジェクトをArrayListにいれて、さらに、1日分のArrayLisのオブジェクトを1ヶ月のArrayListにいれました。 そこで、1ヶ月のArrayListのオブジェクトから1日のArrayListのオブジェクトに分解して、表示したところに、最後の日にちの件数が表示されました。 1.ArrayListにオブジェクトをいれますと、うまく表示されます。 2.ArrayListにArrayListオブジェクトをいれまして、総件数を表示したら、1日から31日までのArrayListのsizeメソッドが最後の日にちが表示されます。よって1日から30日のArrayListに31日分のArrayListが上書きされているように思われます。 1と2の違いと原因をご教授下さい。 //arraylist作成1ヶ月分。 public ArrayList setMonth(int year,int month,int user_id){ -省略- ArrayList monthList=null; for(int count=1; count<=day; count++){ monthList=new ArrayList(); ArrayList dayList=new ArrayList(); dayList=setDay(year,month,count); monthList.add(dayList); } for(int a=0; a<monthList.size(); a++){ ArrayList saa = (ArrayList)monthList.get(a); int mm= saa.size(); System.out.println("mm:"+mm); } return monthList; -省略- } //ArrayList作成1日分 public ArrayList setDay(int year,int month,int day){ ArrayList aList = new ArrayList(); -省略- while(rs.next()){ Allday schAll=new Allday(); schAll.setSchedule_id(rs.getInt("schedule_id")); schAll.setContents(rs.getString("contents")); aList.add(schAll); } for(int b=0; b<aList.size(); b++){ int si= ((Allday)aList.get(b)).getSchedule_id(); String con=((Allday)aList.get(b)).getContents(); } return aList; -省略- }

    • ベストアンサー
    • Java
  • VC++ .net のArrayListについて

    教えてください。 環境: VC++ .net 2003(Framework) 内容: ArrayListについて質問があります。 <.cpp> : : ArrayList* Al = new ArrayList(); samObj obj = new samObj(); obj->set_aaaa(S"うまくいかないよ"); Al.Add(obj); Console::WriteLine(Al->get_item(i)->get_aaaa()); : : <.h> (sam_objctの中身) : : __property void set_aaaa(String* value){mstraaaa = value->Trim();} __property String* get_aaaa(){ return mstraaaa->Trim(); } : : 上記のようにsam_objctに入れたものをitem(i)を使って呼び出したのですが、Alにはaaaaプロパティは存在しません。記述方法が違っているのでしょうか? VBやC#やMFCでは出来たと思っていたのですが・・・・

  • javaのarraylistについて

    あるクラスでArrayListを使って オブジェクト変数を保存したんですけど その保存したオブジェクト変数をほかのクラスで使用するにはどうしたらいいでしょうか? 例えば クラスAでクラスBのオブジェクトを作成し そのオブジェクト変数をArrayListに保存しました クラスCでArrayListに保存したオブジェクト変数を呼び出したいです 初心者なので何を言ってるのかわからないかもしれないですけど よろしくお願いします

  • ArrayListに格納したクラス内のメンバの呼び出し方法(VB)

    お世話になります。VB2003でご質問があります。 通常Arryalistでは下記例1のように使用するのが一般的だと思うのですが、例2のようにArryaListにクラスを追加し、その中のメンバを呼び出すにはどのようにコーディングすればよいのでしょうか? コメントのコンパイルエラー箇所の部分です。 お手数ですが、ご教授よろしくお願いいたします。 ******************************************* (例1) Dim Test as new ArrayList Test.ADD("テスト") console.writeline(test(0)) ******************************************* ******************************************* (例2) Public Class A public strA as string public sub subTest() strA = "おはよう" end sub End Class Public Class B Dim a as new ArrayList a.Add(new A) a(0).subTest '--コンパイルエラー箇所 console.writeline(a(0).strA) '--コンパイルエラー箇所 End Class *******************************************

  • ArrayListからの要素の取り出しについて

    質問いたします。 下記コードの目的は Textクラス内でTest.txtの読み込み・表示を行います 次にErrorクラス内では 【errorRead() 】Testクラスで発生する可能性があるエラーを記載したError.txtよりその内容を読み取りその内容をArrayListクラスのerrorListオブジェクトに格納しておきます。 【setErrorMsg】ではerrorListに格納された要素から必要なエラー表示を取り出す処理をしています。 質問は各クラスのメソッドで起こったエラーをキャッチした場合【setErrorMsg】メソッドへ対応する要素の番号を渡し、errorListよりgetメソッドを使い要素を取得しTestクラス内のcatch部分でその内容を表示させたいのですが、表示の仕方が良くわかりません。 class Test{ public static void main(String[] args){ try{ メソッドの呼び出し }catch(FileNotFoundException fnfe){ エラー内容の表示 }catch(IOException ie){ エラー内容の表示 } } class abc{ public voidTextRead() throws FileNotFoundException, IOException{ try{ 外部ファイルaaa.txtの読み込み、DOS画面への表示処理 }catch(FileNotFoundException){ error.setERROR_MESSAGE(0); }catch(IOException){ error.setERROR_MESSAGE(1); } } class Error{ public void errorRead() throws FileNotFoundException, IOException{ ArrayList errorList = new ArrayList(); try{ BufferedReader br = new BufferedReader(new FileReader("Error.txt")); while((errorStr = br.readLine()) !=null){ errorList.add(errorStr); } br.close(); }catch(FileNotFoundException fnfe){ setERROR_MESSAGE(3); }catch(IOException ie){ error.setERROR_MESSAGE(4); } public int setErrorMsg(int count){ errorList.get(count); return count; } } 宜しくお願い致します。

    • ベストアンサー
    • Java

専門家に質問してみよう