2015-06-15 2 views
0

У меня есть набор классов A1 для An такой формы:применять метод можно назвать Java

public class A1{ 

    //constructor method 
    public A1(...){...} 
    //init method 
    public void init(){...} 
    //some class specific method 
    ... 
} 

Я хотел бы убедиться, что метод init всегда вызывается после инициализации класса (возможно, ошибка компиляции или какое-то предупреждение, если не используется).

Что-то вроде:

A1 a1=new A1(...); 
//some other code that may relate to a1 (e.g. changing default global values) 
a1.init(); // <-- if not used some bad things happens. 

Единственное ограничение:

, что я не могу использовать метод init() в конструкторе

Так есть ли способ сделать это? (за исключением вызова init() в конструкторе, конечно).

+1

В целом нецелесообразно применять конкретный порядок вызовов методов в объектах (хотя иногда это неизбежно). Предпочтительным способом является использование строителей или состава в этих случаях. – biziclop

ответ

1

Создайте в булевом классе значение false, установите значение true в init() и избегайте вызова любого метода, если не true.

public class A1{ 

    boolean initialized = false; 

    //constructor method 
    public A1(...){...} 

    //init method 
    public void init() 
    { 
     // do init stuff 
     initialized = true; 
    } 

    //some class specific method 
    public void myMethod() { 
     if(!initialized) { 
      // print error 
     } else { 
      // do your stuff 
     } 
    } 
    ... 
} 
+0

И если вы забудете добавить его только одним способом ... – biziclop

+1

это умно. никогда не думал об этом – nafas

+0

, если вы забыли добавить валидацию ** в любую часть вашего кода ** плохие вещи будут всегда ... не только здесь;) –

2

Вы можете извлечь тело метода init() в блок инициализатора. Что-то вроде:

public class A1 { 
    { 
     //here goes the body of the init() method 
     //this will always be executed before the constructor 
    } 

    //constructor 
    public A1() { } 
} 

Он будет выполнен до создания каждого экземпляра класса (то есть перед конструктором).

Когда вы создаете экземпляр класса с помощью A1 instance = new A1(), тогда выполняется инициализация блока , а затем тело конструктора будет выполнено. И это касается каждого экземпляра класса, который вы создаете.

+0

hmm intersting concept, если я сделаю это, когда именно этот кусок кода будет выполнен? например сразу после инициализации метода или после того, как я изменил некоторые значения по умолчанию? – nafas

+0

Выполняется * перед * выполняется тело конструктора. –

4

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

public class A1{ 

    //constructor method 
    private A1(...){...} 
    //init method 
    private void init(){...} 
    //some class specific method 
    ... 
    public static A1 create(...) { 
     A1 ret = new A1(...); 
     ret.init(); 
     return ret; 
    } 
} 

Использование статических фабричных методов вместо конструкторов могут быть предпочтительнее по другим причинам тоже, вы можете дать им более выразительные имена и вы можете перегрузить их в вы не можете перегружать конструктор.

P.s .: Вы можете узнать больше об этом в Эффективной Java Josh Bloch, это пункт 1, но другие советы по созданию объектов могут быть подходящими и для вашего случая.

+0

hmm, это сработает, если я собираюсь использовать API, к сожалению, в зависимости от использования может меняться набор значений по умолчанию (некоторые коды между конструктором классов и методом init) – nafas

+0

Это код может быть введен в качестве стратегии. Но, как вы это описываете, похоже, что есть некоторые проблемы с дизайном. Почему должен существовать код между созданием 'A1' и вызовом метода' init() ', который не использует вновь созданный объект, но влияет на' init() '? – biziclop

+0

вы, безусловно, умны, но поскольку существует много классов, и я старался, чтобы дизайн был очень прост в использовании, поэтому другие могут просто использовать их с минимальной разницей между тем, как определить классы. конечно, обратная сторона заключалась в том, что если кто-то хочет изменить значения по умолчанию, они должны сделать это до вызова метода 'init'. – nafas

Смежные вопросы