2015-07-13 4 views
5

Итак, я создаю тестовую библиотеку, которую я буду использовать в основном для личного использования, однако у меня есть вопрос.Throw Exception, а затем Call Constructor?

С Java, если у вас есть 2 или более конструктора в вашем классе, если вы хотите позвонить друг другу, это должно быть первое, что вы делаете. Это проблематично для меня, поскольку у меня есть следующая настройка.

public Constructor(TypeA a, TypeB b, TypeC c) { 
    if (c.getData() == null) throw new IllegalArgumentException(""); 
    this(a, b, c.getOtherData()); 
} 

public Constructor(TypeA a, TypeB b, TypeD d) { 
    // stuff happens 
} 

Как я могу это сделать, избегая, «Конструктор вызов должен быть первым оператором в конструкторе» ошибка?

+0

Вы не можете делать то, что хотите. – bhspencer

+2

Вместо конструктора рассмотрим статический заводский метод. – bhspencer

+0

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

ответ

4

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

public static TypeThing buildMyThing(TypeA a, TypeB b, TypeC c) { 
    if (c.getData() == null) throw new IllegalArgumentException(""); 
    return new TypeThing(a, b, c.getOtherData()); 
} 

public Constructor(TypeA a, TypeB b, TypeD d) { 
    // stuff happens 
} 
0

У вас может быть дополнительный частный конструктор. Я предполагаю, что вы упростили код здесь слишком много. Вы говорите, что если что-то нулевое, тогда бросайте - иначе вы что-то еще.

public Constructor(TypeA a, TypeB b, TypeC c) { 
    this(a, b, c.getData(), c.getOtherData()); //calls the private ctor 
} 

public Constructor(TypeA a, TypeB b, TypeD d) { 
    // stuff happens 
} 

private Constructor(TypeA a, TypeB b, TypeD d1, TypeD d2) { 
    // stuff happens 
} 

или вы могли бы просто передать в TypeC

private Constructor(TypeA a, TypeB b, TypeC) { 
    // now do you null check here. 
} 

Java действительно вызывает некоторые боли иногда! а затем это правило является одним из них. В конкретном ответе на ваш вопрос о ошибке компиляции - вы не можете :(

3

Один из вариантов (возможно, плохо): Проверка на getData == null and throw the exception as first thing in c.getOtherData() `Это будет первый метод выполняется

..

Другой вариант: есть способ, как,

helper() { 
    if (getData() == null) throw new Exception(); 
    return getOtherData(); 
} 

и от вас конструктора, вызовите c.helper() вместо c.getOtherData()

+0

Для вашего второго варианта вы должны сделать вспомогательный финал, чтобы избежать проблем с «Overridable method call in constructor». – Drunix

0

Попробуйте переместить исключение, отправленное в начало второго конструктора. Это достигнет того же самого. Если есть несколько путей к этому конструктору, вы можете сделать дополнительный параметр, который сигнализирует логический путь.

+0

Я не могу этого сделать ... Как только я вызываю 'c.getOtherData()', я теряю 'c.getData()' – Spedwards

+0

В этом случае похоже, что вы просто используете getData() в качестве логического маркера в данном конкретном случае. Возможно, вы захотите добавить логический параметр в самый нижний конструктор, обозначающий, был ли getData пустым. при вызове он выглядел бы так: –

+0

Конструктор (a, b, c.GetData() == null, c.GetOtherData()) –

2

Как насчет создания статического метода фабрики?

public static Constructor newInstance(TypeA a, TypeB b, TypeC c) { 
    if (c.getData() == null) throw new IllegalArgumentException(""); 
    return new Constructor(a, b, c); 
} 

private Constructor(TypeA a, TypeB b, TypeC c) { 
    this(a, b, c.getOtherData()); 
} 

private Constructor(TypeA a, TypeB b, TypeD d) { 
    // stuff happens 
} 
+0

В этом, почему бы вам просто не отказаться от первого конструктора и иметь фабрику метод возвращает второй конструктор? – Spedwards

+0

@Spedwards Я не был уверен, как именно вы использовали первый конструктор, поэтому я не хотел его удалять, но если вы считаете, что это жизнеспособно, тогда вы можете это сделать. –