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

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

詳細はこちら
Java

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

Q&A

解決済

3回答

3018閲覧

Java 返り値の型を場合分け

yochun02

総合スコア76

Java

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

0グッド

1クリップ

投稿2021/02/08 05:15

編集2021/02/08 05:36

以下の様に、返り値の型が実行されるまで未定であるメソッドの書き方がわかりません。ジェネリクスを使うと思うのですがどう実装したらよいでしょうか?

java

1 2public class Test { 3 4 // 引数に"string"か"int"でlistに入った 5 public List<> add(String str) { 6 List<> list = new ArrayList<>(); 7 if(str == "string") { 8 list.add("hoge"); 9 list.add("fuga"); 10 } 11 if(str == "int") { 12 list.add(1); 13 list.add(2); 14 } 15 } 16 return list; 17} 18 19// 期待値 20Test.add("string") // ["hoge", "fuga"] 21Test.add("int") // [1, "2]

ジェネリクスを用いて見様見真似で書いたもの

java

1 public <T> List<T> add(String str) { 2 List<T> list = new ArrayList<>(); 3 if(str == "string") { 4 list.add((T) "hoge"); 5 list.add((T) "fuga"); 6 } 7 if(str == "int") { 8 list.add((T) 1); 9 list.add((T) 2); 10 } 11 return list; 12 }

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2021/02/08 09:04

最終的に何がやりたいのかを書いてください。 方法を調べている中でジェネリクスに出会ったのだと思うのですが・・・。
guest

回答3

0

ベストアンサー

javaでは、一般的に動的な型を使わないです。
なので、今回の例だとメソッドを2つ書きます。

if文の分岐の中を別に書くだけなので、特に難しくないとおもいます。
メンテナンスも、if文の中を読まなくてもメソッド単位で探せるので、こちらの方が楽です。

java

1public static void main(String[] args) { 2 Test hoge = new Test(); 3 4 List<String> sList = hoge.addString(); 5 System.out.println(sList); 6 7 List<Integer> iList = hoge.addInt(); 8 System.out.println(iList); 9} 10 11public List<String> addString() { 12 List<String> list = new ArrayList<>(); 13 list.add("hoge"); 14 list.add("fuga"); 15 16 return list; 17} 18 19public List<Integer> addInt() { 20 List<Integer> list = new ArrayList<>(); 21 list.add(1); 22 list.add(2); 23 24 return list; 25} 26

あと型がString or Intのみ

ということが分かっていた場合に、これらのどちらかの型に制約できるのでしょうか?

上記のメソッド以外は存在しないので、呼べません。(コンパイルエラー)

どうしても1つのメソッドでやりたいなら、ワイルドカードというのがあります。

java

1public static void main(String[] args) { 2 Test hoge = new Test(); 3 4 List<?> sList = hoge.add("string"); 5 System.out.println(sList); 6 7 sList = hoge.add("int"); // ワイルドなので、代入可能 8 System.out.println(sList); 9 10 sList = hoge.add("empty"); 11 System.out.println(sList); 12} 13 14public List<?> add(String str) { 15 if ("string".equals(str)) { 16 List<String> list = new ArrayList<>(); 17 list.add("hoge"); 18 list.add("fuga"); 19 20 return list; 21 } 22 23 if ("int".equals(str)) { 24 List<Integer> list = new ArrayList<>(); 25 list.add(1); 26 list.add(2); 27 28 return list; 29 } 30 31 return new ArrayList<>(); // return null; 32} 33

とはいえ、型定義がList<?>なので、自前でCastしないといけないし
型が違えば例外が発生するしで使いにくくて仕方ありません。
まぁ、型付けの厳しい言語への慣れなので好みとも言えますが。

ご提示の

public <T> List<T> add(String str)

を使う場合は、どうしてもワーニングは防げないです。
また、実際に以下のように呼び出しても

java

1List<Integer> iListFake = hoge.add("string"); 2System.out.println(iListFake.get(0).doubleValue()); 3

Integerが入ったListでなく、Stringが入ったListが返ってくるので
コンパイルエラーになりませんが、実行時に例外(ClassCastException)が発生します。

なので、javaの場合は、おとなしく2つのメソッドに分けた方が良いと思います。
2つにわけるのはよいが、どうしても同じ名前を使いたい場合は、引数に型を指定するのも
まぁありかと思います。(正直ダサいと思いますが)

java

1public List<String> add(String s) 2public List<Integer> add(int i) 3

投稿2021/02/08 08:16

momon-ga

総合スコア4826

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

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

0

以下の様に、返り値の型が実行されるまで未定であるメソッドの書き方がわかりません。

なぜそのようなメソッドを書く必要が生じたのでしょうか?それを必要とする設計段階から見直しが必要かもしれません。

投稿2021/02/08 07:52

編集2021/02/08 07:53
maisumakun

総合スコア145975

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

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

Zuishin

2021/02/08 08:35

見直しが必要となる可能性も高いとは思いますが、Scala の Either のようなものを使いたい可能性もあるのではないかと思います。
guest

0

あまり良くはないと思うけど
Object

投稿2021/02/08 05:30

m.ts10806

総合スコア80875

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

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

m.ts10806

2021/02/08 05:31

ジェネリクスが…と目処があるならまず思ったように書いてみればいいと思う
yochun02

2021/02/08 05:40 編集

補足の様に書いてみたんですが、コンパイル時にキャストの警告出てしまいます。 警告:[unchecked] 無検査キャスト Tが型変数の場合: [javac] メソッド <T>add(String)で宣言されているT extends Object
yochun02

2021/02/08 05:41 編集

@SupressWarnings(“unchecked”)をつけて見なかったことにはできますが、最終手段にしたいです
yochun02

2021/02/08 05:49 編集

あと型がString or Intのみ ということが分かっていた場合に、これらのどちらかの型に制約できるのでしょうか?(typescriptみたいにString | Intとかしたい。。。)
m.ts10806

2021/02/08 05:49

型が不定な実装は避けられたほうがいいかなと。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問