私はUniを離れて以来、Javaを悩まして、それは私の上に押しつけられています。私はいくつかのコードをリファクタリングしようとしており、私がしたいところにほとんどの道を持っています。残念ながら、私は1つの厄介なコードが残っています。この時点でサブクラスにキャストする必要がありますが、より良い方法があるはずです。誰かがその良い方法で助けることができれば、私はそれを感謝します。Javaジェネリックスを理解する - これをよりうまく行えますか?
public abstract class Protocol {
protected Class<? extends ProtocolConfiguration> configClass;
public void open() {
ProtocolConfiguration config = HighAvailabilityConfiguration.create(configClass, this.getProtocolName());
config = this.preprocessConfig(config);
// blah
}
protected ProtocolConfiguration preprocessConfig(ProtocolConfiguration protocolConfig) {
return protocolConfig;
}
}
public class InteractionProtocol extends Protocol {
public InteractionProtocol() {
this.configClass = InteractionProtocolConfiguration.class;
}
@Override
protected ProtocolConfiguration preprocessConfig(ProtocolConfiguration protocolConfig) {
// *** Is it possible to operate on protocolConfig as InteractionProtocolConfiguration without casting? ***
InteractionProtocolConfiguration config = (InteractionProtocolConfiguration) protocolConfig;
config.setClientName(ClientName); // does not exist on base class
return config;
};
}
私はプロトコルを拡張するいくつかのクラスを持っています。それぞれは、独自の特定の種類のProtocolConfigurationクラスについて知る必要があります。その理由は、私はProtocolConfigurationFactoryを持っていて、ほとんどの完全な設定項目を生成するためにクラスタイプを取るからです。私は工場やConfigurationクラスを制御しません。彼らは私が使っている図書館の一部です。しかし、プロトコルを開くことは、各サブクラスの設定でいくつかのカスタムプロパティを設定するという要件を除いて、すべてのプロトコルで共通です。
編集:参考
、私は)(HighAvailabilityConfiguration.createためのコードを提供します。
public static <T extends ProtocolConfiguration> T create(Class<T> clazz, String protocol) throws ConfigException {
T config;
try {
// get the constructor that only takes a String
@SuppressWarnings("unchecked")
Class<String>[] ctorArgs1 = new Class[1];
ctorArgs1[0] = String.class;
Constructor<T> ctor = clazz.getDeclaredConstructor(ctorArgs1);
config = ctor.newInstance(protocol);
} catch (Exception e) {
Log.error(e);
throw new ConfigException("Could not create ProtocolConfiguration for " + protocol);
}
...
return config;
}
上記のコメントもありますが、当分の間は問題ありません。
これは私が現在試みていることです。しかし問題は、createメソッドのthis.getClass()です。 T.classである必要がありますが、これは許可されていません。 –
私は既に派生コンストラクタにクラスを作成していました。私もそれを排除しようとしていましたが、それはドッジ・キャスティングの問題ではありません。私はまた、 '再帰ジェネリック'パラメータ(実際の名前ではない)を提供することによって、ベースクラスのサブクラスへの参照を取得しようとしていました。短い答えは、私が物事を過度に複雑化しようとしなければ、これは完全に機能します。 –
私が言ったように私はエディタでそのコードをカットしていないので、私は確認していません。私は 'this.getClass()'がInteractionProtocolクラスを返すので、このトリックを行うと思っていたでしょう。代わりに、 'private Class clazz;という変数を設定することもできますし、コンストラクタとして渡すこともできますが、' getClass() 'はこの場合にはうまくいきません。 –
drekka