🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Java

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

Q&A

解決済

3回答

2093閲覧

拡張for文「配列とStringには互換性がない」とは

ATTOMAN

総合スコア40

Java

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

0グッド

0クリップ

投稿2019/11/24 04:21

編集2019/11/24 05:25

前提・実現したいこと

Java silver SE8の拡張for文に関する問題で分からない所があったので質問させていただきます。
次のプログラムの4行目for( )の空欄に記述するコードを選択肢から選ぶ問題です。

public class Main { public static void main (String[] args) { String[][] array = { {"A","B","C"} }; for(         ) { System.out.print(obj); } } }

私が迷った選択肢は
A.Object obj : array
B.String str : array
この二択です。

私は "5行目 System.out.print(obj); で 変数objを呼び出しているから" 選択肢Aだと考えました。
正解はAなのですが、解説には
『選択肢Bは、2次元配列の集合から取り出した2次元目の配列を受け取る必要があるにもかかわらず、String型で変数を宣言している。配列とStringには互換性がないため、コンパイルエラーが発生する。』
とあり、この解説が理解できません
(´;ω;`)配列を呼び出す拡張for文でString型の変数は使ってはいけないという意味だろうか...
などと考えていたのですが次のコードからそうではないことは分かりました。

下のコードは先のコードを2次元配列から1次元配列に変え、変数をstrにしたものです。これをコンパイル、実行するとコンパイルエラーは起きず、「ABC」と表示されます。

public class Main { public static void main(String[] args) { String[] array = {"A","B","C"}; for (String str : array) { System.out.print(str); } } }

この二つのコードの違いと合わせて、上の解説の意味を教えていただきたいです。
よろしくお願いいたします。

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

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

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

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

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

Zuishin

2019/11/24 04:25

試してないので間違ってるかもしれませんが、コンパイルエラーおきませんか?
ozwk

2019/11/24 04:29

> コードを2次元配列から1次元配列に変え なんで?
BeatStar

2019/11/24 04:34

下は paiza IO で試すとエラー吐きます。( String[][] がString[] になっている )
raccy

2019/11/24 04:46

そもそもforの中身で変数`obj`を使っている時点で変数`str`を使うような選択肢があること自体がおかしい気がします。Oracle公認の試験でこのレベルの問題が出るとなると、OracleはまじでJavaを見捨てようとしている気がしてきました。
ATTOMAN

2019/11/24 04:56

試すのに少し時間がかかってしまい返信遅くなりました。ごめんなさいm(_ _"m) コードが間違っていました。ご指摘ありがとうございます。 {{"A","B","C"}}ではなく{"A","B","C"}でした。 すみません よろしくおねがいします。
Zuishin

2019/11/24 05:26

> Oracle公認の試験でこのレベルの問題が出るとなると、OracleはまじでJavaを見捨てようとしている気がしてきました。 どういう試験なのかググってみました。 https://proengineer.internous.co.jp/content/columnfeature/4607 > 「新Silver」はJavaによるオブジェクト指向プログラミングを理解できているかどうかが問われる内容で、新人プログラマ向けだった「旧アソシエイツ」相当の難易度と考えられます。 これに合格すると新人プログラマーレベルと認められるという何とも意味不明な資格ですね。
guest

回答3

0

ベストアンサー

互換性があるかどうかというのは、要はその型の変数に代入できるかということです。早い話、次のどちらならできますか?ということ。

java

1//A 2Object obj = array[0]; 3 4//B 5String str = array[0];

array[0]String[]型であるため、Object型には代入できますが、String型には代入できません。

投稿2019/11/24 04:55

swordone

総合スコア20669

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

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

ATTOMAN

2019/11/24 05:18

回答ありがとうございます。 すみません、まだ完全に理解できていないのですが、 上のコードはString[]型をString型には代入できず、Object型なら代入できる。 下のコードではSting型をString型に代入しているだけだから可能。 ということでしょうか
swordone

2019/11/24 05:30

はい、そうです。
ATTOMAN

2019/11/24 06:13

分かりました!素早い回答をどうもありがとうございました
guest

0

これ、いやらしい問題ですね。
まったく方向性の違うものを出すって...
犬と人間を同一視するようなものですし。

String[][] array = { {"A","B","C"} };

は、図にするとわかりやすいです。

// それぞれのデータをString型として. "A", "B", "C" "D", "E", "F" "G", "H", "I" "J", "K", "L" ...

のように表みたいになっています。(厳密には違いますが...)

今回はそのうちの "A"~"C" がセットされている状態です。

その { "A" } というデータを取り出すためには texts[0][0] のようにして取り出します。

Java

1// 二次元配列の名前がtextsだとして 2System.out.println( texts[0][0] );

という風に取り出します。

つまり、拡張forで取り出そうとすると、(あまりに次元配列は使わないのであくまでイメージ)
Stringの配列 ( 一次元 ) を取得してからになると思います。

それを String[] ではなく String で取得しようとしているため、型が合わないことからエラーを吐く。

ただ、出題がおかしい。

鶏を生き物だからと言って、人間と同一(まったく同じとして)とみなすような出題なのでいやらしいなぁと。


[追記1]

あまりJavaは(仕様レベルでは)よくわかっていませんが、ソースは忘れましたが、『JavaではすべてのオブジェクトはObjectクラスを継承していると考えられる』系の説明を読んだことがあります。

一応Javaのdocumentationでも

Objectクラスは、クラス階層のルートです。すべてのクラスは、スーパー・クラスとしてObjectを持ちます。配列を含むすべてのオブジェクトは、このクラスのメソッドを実装します。

とあります。

『配列を含むすべてのオブジェクト』とあるので、String[] でも String[][] でも Stringでも Objectを継承していると想定されるために、

// String[][] texts だとして for( Object obj : texts )...

でも受け取れるのだと思います。

ですが、for( String obj : texts ) ... という風に Stringで受け取ろうとすると、配列なのに変数に入れるような状況になってしまうので、コンパイルエラーを吐く。

Objectクラスは 配列を含めたオブジェクトすべてに実装されていると想定されているので、そのまま使える。

...っていうことなんだと思います。

投稿2019/11/24 05:13

編集2019/11/24 05:41
BeatStar

総合スコア4962

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

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

ATTOMAN

2019/11/24 06:15

配列についてだいぶイメージができてきました 丁寧な回答どうもありがとうございます!
guest

0

配列は、Object変数には代入できるが、String変数には代入できないということでは?

下のプログラムはコンパイルエラーですが、リテラル部分を1次元配列に直すと、String変数に文字列を代入しているだけなので、問題ないです。

投稿2019/11/24 04:35

otn

総合スコア85882

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

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

ATTOMAN

2019/11/24 06:17

素早い回答、ありがとうございました! 無事、理解することができましたm(_ _"m)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問