2015-09-02 4 views
3

Я играю с созданием фабричного метода для генерации RuntimeExceptions.Java Generics, обеспечивающий параметры Enum

Идея заключается в том, чтобы выбросить исключение, выполнив следующий фрагмент:

throw ExceptionFactory.build(CustomException.class, CustomException.NOT_FOUND); 

Первый параметр метода сборки является класс исключения, однако второй параметр будет ссылаться на Enum, который определен в пределах CustomException класс для загрузки дополнительных сведений при построении исключения.

Пример:

public class CustomException extends RuntimeException { 

    public static final ExceptionType NOT_FOUND = ExceptionType.NOT_FOUND; 



    //constructors, getters, setters, etc.. 



    private enum ExceptionType { 

    NOT_FOUND(Status.NOT_FOUND, "These aren't the droids you're looking for!"); 

    private Status status; 
    private String description; 

    private ExceptionType(Status status, String description){ 
     this.status = status; 
     this.description = description; 
    } 

    //other methods here.. 

    } 

} 

вопрос у меня есть с ExceptionFactory.build(), как указать параметры для метода сборки() таким образом, что второй параметр должен быть специфическими для класса CustomException ?

Если этот подход кажется сумасшедшим, как его можно улучшить? Цель состоит в том, чтобы иметь общий заводский метод для создания исключений, у которых есть уже загруженные детали. То, что я хочу, чтобы избежать это что-то вроде этого ..

ExceptionFactory.build(CustomException.class, "Some string...") 

Идея заключается описание должно быть определено в CustomException, а не только что-либо при броске ошибку. Итак, как обеспечить соблюдение?

public class ExceptionFactory { 

    public static <T extends RuntimeException> T build(T e, ???){ 
    //more logic here... 
    } 

} 
+0

Разве что у вас есть несколько разных настраиваемых типов исключений, каждый из которых имеет такую ​​вещь перечисления? Я не думаю, что это может произойти. Возможно, вы можете использовать синтаксис, похожий на построитель, вместо перечисления? –

+1

@ byte-crunch, язык параметров типа Java не имеет средств для описания типа в терминах его содержащего типа. Идея Слэкса могла бы работать, но я не думаю, что это или твоя стартовая идея фактически приведет тебя туда, где ты действительно хочешь быть. –

+0

Да, было бы несколько классов типа «CustomException», каждый из которых имеет внутреннее перечисление, определяющее особенности генерирования этого конкретного исключения.То, что я хотел сделать, это иметь общий метод «build», который принимает первый параметр для определения класса исключения, а затем на основе этого класса применяет допустимые инструкции во втором параметре. –

ответ

3

Вы можете использовать интерфейс маркера:

interface ExceptionTypeEnum<T extends RuntimeException> {} 

private enum ExceptionType implements ExceptionTypeEnum<CustomException> { 
    ... 
} 

public static <T extends RuntimeException> T build(T e, ExceptionTypeEnum<T> type) { 
1

Вместо того, чтобы использовать ExceptionFactory что-то что-то, один из способов реализации этого будет использовать фабричные методы в ваших типов исключений. Например:

public class CustomException extends RuntimeException { 
    private CustomException(String description) {...} 
    public static CustomException notFound() { 
    return new CustomException("not found"); 
    } 
    .... 
} 

Это гарантирует, что любые CustomException пользователи вашего кода ГЭТ происходит от одного из ваших фабричных методов, которые населяют сообщение об исключении с информацией, которую вы выбрали. Вы также можете добавить все аргументы, которые вы хотите использовать для статических заводских методов, поэтому разные причины исключения могут потребовать разные параметры в заводском методе.

1

Я не уверен, что на самом деле вижу большую ценность в том, что вы предлагаете делать. Мне непонятно, как сложный фабричный механизм генерации исключений улучшается при непосредственном их создании там, где и когда они нужны. Тем не менее, вы можете подойти к этой проблеме, сделав свои перечисления более функциональными.

Например,

public interface ExceptionEnum { 
    public Class<? extends RuntimeException> getExceptionClass(); 
} 

public class CustomException extends RuntimeException { 

    enum Details implements ExceptionEnum { 
     GOOD, BAD, UGLY; 

     public Class<? extends RuntimeException> getExceptionClass() { 
      return CustomException.class; 
     } 
    }; 

    // ... 
} 

// ... 

throw ExceptionFactory.build(CustomException.GOOD); 

ExceptionFactory.build() нужно только потребовать аргумент типа ExceptionEnum.