質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

キャスト

キャストとは、オブジェクトの型の変換が許可された場合に、明白に別の型への変換を行うプロセスのことです。

Q&A

解決済

4回答

14961閲覧

java キャストが上手くいきません。

kaori1994

総合スコア28

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

キャスト

キャストとは、オブジェクトの型の変換が許可された場合に、明白に別の型への変換を行うプロセスのことです。

0グッド

0クリップ

投稿2016/10/28 01:17

お世話になっております。kaoriと申します。

javaで学習をしておりますが、キャストで壁にぶつかってしまいました。
どのタイミングのキャストが上手くいってないのか、ご教示いただけたらと思い。投稿いたしました。

【やりたいこと】
List型(String)で送られてきた配列をmapのValueとして使いたい。

//serviceのsearchメソッドに引数を渡し、listで値が返ってきます。 List<data> resultData= service.search(引数); //resultDataをObject[]型にキャスト Object[] objs = resultData.toArray(new Object[resultData.size()]); //objsをString[]型にキャスト String[] strs = (String[])objs; //mapのvalueにstrs[]を使用したい Map<String, String> map = new HashMap<>(); map.put("id", strs[0]); map.put("name", strs[1]); map.put("telNo", strs[2]); [エラー分] java.lang.ClassCastException:

オブジェクトを継承関係にないクラスにキャストしようとしたことが問題だと出てきました。
このコード的には問題ないが、クラスの継承関係が正しくないために、正しくキャストされないということでしょうか。
それともコード事態に問題があるのでしょうか。

ご教示いただけると幸いです。よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

それともコード自体に問題があるのでしょうか。

書き方自体に問題があります。Listの要素型のdata型はString型と互換性がありませんのでキャストでなんとかしようとしてもNGです。Stringとして扱うには何らかの方法で明示的にStringへ変換しなければなりません。

java

1List<data> resultData= service.search(...); 2String[] strs = list.stream() 3 .map(d -> d.toString()) // この例では単純にtoStringでStringへ変換 4 .toArray(size -> new String[size]); 5あるいは 6List<data> resultData= service.search(...); 7String[] strs = new String[resultData.size()]; 8for (int i = 0; i < strs.length; i++) { 9 strs[i] = resultData.get(i).toString(); 10}

投稿2016/10/28 01:50

KSwordOfHaste

総合スコア18394

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

swordone

2016/10/28 01:58

ちなみに、toArrayのところは toArray(String[]::new)と書けます。
kaori1994

2016/10/28 02:19

ご回答ありがとうございます。 例として二点も挙げていただき感謝いたします。 両方理解してから実行して動作確認したいと思います。 ありがとうございます。
KSwordOfHaste

2016/10/28 03:40 編集

>toArrayのところ なるほどメソッド参照ですね。コメントありがとうございます。>swordoneさん
guest

0

String[] strs = (String[])objs;で落ちています。

objsはオブジェクト型の配列で、Stringは継承してないのでエラーになります。(objectはすべてのクラスが暗黙に継承しています。逆に言うとどれにもキャストすることができません。)

Exceptionが出ているということは、コンパイルは問題なく実行時にエラーがでています。
継承関係を間違えているんですが、自明なエラーだといえます。


間違えていました。

ほかの方の指摘通り、data型がStringを継承していないのでエラーになっているようです。

投稿2016/10/28 01:40

編集2016/10/28 02:07
iwamoto_takaaki

総合スコア2883

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

swordone

2016/10/28 01:45

いや、Objectの変数にStringオブジェクトが入っていればキャストはできます。 Javaの配列の場合はそれが配列であっても(中身がキャストできれば)キャスト可能なのでコンパイルエラーは出ないのですが、中身がキャストできなければ例外になります。
iwamoto_takaaki

2016/10/28 02:00

配列には共変性ありましたね。指摘ありがとうございます。
kaori1994

2016/10/28 02:17

ご回答ありがとうございます。 「配列には共変性がある」という新たな情報がいただけてうれしいです! javaに慣れている方も、一瞬忘れてしまうように javaのキャスト関係は複雑で、もっと勉強する必要があると改めて痛感いたしました。 ありがとうございました。
guest

0

先頭行で書かれているList<data>の data が何の型か書かれていませんので正確ではないかも知れませんが、

dataのクラスにてStringで宣言されているフィールドを取り出してMapへ格納したい?のでしたら、例えば
フィールドvalueに取得したい内容があるとして、data.getValue() で取得したい文字列が得られるとするならば、

java

1Map<String, String> map = new HashMap<>(); 2map.put("id", data.get(0).getValue()); 3map.put("name", data.get(1).getValue(); 4map.put("telNo", data.get(2).getValue());

で良いかと思います。

投稿2016/10/28 01:40

A-pZ

総合スコア12011

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kaori1994

2016/10/28 02:12

ご回答ありがとうございます。 このような方法もあるのですね。参考にさせていただきます! ありがとうござます。
guest

0

ベストアンサー

java

1//resultDataをObject[]型にキャスト 2Object[] objs = resultData.toArray(new Object[resultData.size()]);

ここでやっていることは「キャスト」ではなく、resultDataをObjectの配列に入れている、というものです。
つまり、resultDataの中のdata(どういうクラスか不明ですが)という型のオブジェクトを、配列の中に用意されたObject型変数に次々代入しているような形です。代入しているだけで、オブジェクトの実体の型はdata型のままです。

java

1//objsをString[]型にキャスト 2String[] strs = (String[])objs; 3```上記の通り、objsはObjectの配列ですが、実行時の中身はdata型のオブジェクトです。 4これをStringの配列にキャストしようとするわけですが、**中身のdataをStringにキャストできないので、例外が発生します。** 5そもそもここで使っているように、Javaの配列には共変性(配列の中身の型同士に継承関係があればキャストできる)があるのでコンパイルエラーにはならないのですが、このように型安全性の問題があり、Javaの失敗と言われているそうです。 6 7というか、これだけなら配列化する必要性がないですよね。`strs[0]`としているところを、(どうしてもStringで入れるとしたら)`resultData.get(0).toString()`とすれば済む話なのでは?

投稿2016/10/28 01:33

swordone

総合スコア20651

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kaori1994

2016/10/28 02:10

ご回答ありがとうございます。とても納得いたしました。 data型をStringにキャストできないのを足掻いて強引にできないか試すより(というよりできないみたいですね) resultData.get(0).toString()このようなオブジェクト型から指定して取得する方法を考えた方が早かったようです・・・ 参考になりました。ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問