35314


Javaのコマンドラインアプリケーションを作っているのですが、どうしてもnew T()相当を実装したいのですが、回避策はないでしょうか。

親クラス

[code]

    public abstract class AbstractCommandLineRunner<T extends AbstractCommandLineOption> implements CommandLineRunner {
    
        protected abstract int execute(T option);
    
        protected abstract T newOptionInstance();
    
        public void run(String... args) {
            // ここで本当はT option = new T()として、newOptionInstance()を排除したい
            T option = newOptionInstance();
            new CmdLineParser(option).parseArgument(args);
        }
    }
    
[/code]

サブクラス

[code]

    public class HogeRunner extends AbstractCommandLine<HogeOption> {
        // このメソッドの実装を省略したい...
        @Override
        protected HogeOption newOptionInstance() {
            return new HogeOption();
        }
    
        @Override
        protected int execute(HogeOption option) {
            // blah blah
        }
    }
    
[/code]

コマンドが増えるたびに下記の手順で、実装するというアーキテクチャにしたいのですが、

  * AbstractCommandLineOptionを継承してコマンド引数を格納するオブジェクトを用意
  * AbstractCommandLineRunnerを継承してexecuteメソッドに処理を実装

CmdLineParserライブラリの都合上、オプションのインスタンスが必要なため、newOptionInstance()というabstractメソッドを定義しています。できればこれを排除して親クラスでインスタンスを作りたいのですが、Javaにおいては困難でしょうか。

  * 開発言語：Java

  * 開発環境：Eclipse

  * フレームワーク：Spring Boot


CC BY-SA 3.0
2017-06-05T03:11:16.360
35284
2017-06-05T15:40:38.273
2017-06-05T15:12:18.053
3068
15316
question
java spring-boot
Javaにおけるnew T()相当


> どうしてもnew T()相当を実装したいのですが、回避策はないでしょうか。

Java言語のジェネリクスでは、型パラメータ`T`から直接インスタンス化することができません。（Java言語仕様で禁止されています）

アドホックな回避策としては、本家StackOverflow [Create instance of generic type in
Java?](https://stackoverflow.com/questions/75175/) の回答群が参考になると思います。

フレームワーク側でよくある対処としては、[`ParameterizedType`を利用したリフレクション(reflection)](https://stackoverflow.com/a/75345/)方式で、サブクラスの型パラメータを取得できます。実際にこの方式が望ましいか否かは状況に応じて判断ください。


CC BY-SA 3.0
2017-06-05T15:40:38.273
35314
2017-06-05T15:40:38.273
49
35284
answer