これはすべてのアプリケーションのケースで機能するわけではありませんが、ジェネリックを使用するライブラリを定式化することは、将来ライブラリを作成してこの質問を検討する人々にとっての解決策になる可能性があります。
たとえば、アプリケーションの「設定」を一般的に管理するライブラリ クラス (SettingsManagerBase) を作成し、これらの設定をコードで取得/設定できる保証された一意のキーが必要でした。だから私は自分のインターフェースを定義しました(ここでは、追加の「セキュリティ」のために受け入れられた回答からのアイデアも取り入れましたが、これは私のアプローチでは厳密に言えば必要ではありません):
// Part of my settings library
public interface SettingBase<E extends Enum<E>> {
Object defaultValue(); // <-- Whatever interface is needed
}
そして私の実装:
// Part of my application that uses the settings library
public enum Setting implements SettingBase<Setting> {
THEME,
SHOW_DIALOGS,
...;
@Override
public Object defaultValue() { ... } // <-- Required interface implementation, probably based on constructor arguments (not shown)
}
ここで重要なのは、設定マネージャー ライブラリ クラスが、SettingBase を実装する列挙型を指定する必要があることを指定することです (これは現在、完全な保証です)。
// Part of my settings library
public abstract class SettingsManagerBase<E extends Enum<E> & SettingBase<E>> {
public void foo(E setting) {
Object d = setting.defaultValue(); // We can safely use all methods from our interface
String n = setting.name(); // We can safely use all enumeration methods, without needing to specify them manually in our interface or anything
}
}
設定マネージャーの実装は次のようになります。
// Part of my application that uses the settings library
public class SettingsManager extends SettingsManagerBase<Setting> {
// If you need to override a function then E just turns into Setting
public void foo(Setting setting) { ... }
}
ライブラリ クラス (SettingsManagerBase) のジェネリック Enum 'E' に対応するクラス インスタンスが必要な場合は、次のようにします。
// Add to SettingsManagerBase
protected Class<E> mEnumClass;
public SettingsManagerBase(Class<E> enumClass) {
mEnumClass = enumClass;
// Now you can do things like call Enum.valueOf(...)
}
// Add to SettingsManager
public SettingsManager() {
super(Setting.class);
}
この答えは私のユースケースに固有のように思えますが、列挙によってインターフェイスを強制的に実装したい他の多くの状況でこのアイデアを実装することは難しくありません。