Спасибо Jon, Peter и Upog за помощь в решении моей проблемы. Я хотел показать реальный код для моей исходной проблемы, а затем показать код для того, что его решило, в надежде, что другие могут извлечь выгоду из этого конкретного случая.
Моей первоначальная проблема заключалась в том, что я не мог увеличивать статический, неповторимый счетчик:
/**
* Generate numbers and increment
*/
public class BuggedGenerator {
/************** Public Constants/Factory ***********/
private static BuggedGenerator INSTANCE = null; // to contain the single instance
/**
* The single instance of BuggedGenerator.
*/
public static final BuggedGenerator READ_IN = getInstance();
public static final int GEN_ID = genID();
private static int base = 999999;
/************ Singleton SetUp ************/
/**
* Utility Constructor.
*/
private BuggedGenerator() {
super(); // unnessesary, but I always invoke super()
}
/**
* Initialize the counter singleton
*/
private static int genID() {
BuggedGenerator.SINGLETON.base += 1;
return base
}
/**
* Determine whether BuggedGenerator already has an instance
* and return that instance.
*/
public static BuggedGenerator getInstance() {
if (null == BuggedGenerator.INSTANCE) {
BuggedGenerator.INSTANCE = new BuggedGenerator();
}
return BuggedGenerator.INSTANCE;
} // end getInstance()
}
Это то, что я получаю от этой реализации:
> BuggedGenerator.READ_IN.GEN_ID
> 1000000
> BuggedGenerator.READ_IN.GEN_ID
> 1000000
> BuggedGenerator b = BuggedGenerator.READ_IN
> b.GEN_ID
> 1000000
В ответе на запрос с помощью, я использовал класс AtomicInteger для замены реализации GEN_ID, как показано в примере Питера, но я получил ошибки времени компиляции в отношении статических инициализаций. Я решил, что было слишком много боли, чтобы идти против ООП и реализовал AtomicInteger как обычный синглтон, являющийся свойством объекта. По предложению Перна я включил весь код вместо моментального снимка. Вы можете использовать:
/**
* Copyright 2013, Phil Reason. preason intisive com
* Permission to copy, modify, resell and or freely distribute - provided an
* exact copy of this file is explicitly accompanied and unaltered alongside
* of any distribution of works using this file or any modified version of
* this file.
*/
import java.util.concurrent.atomic.AtomicInteger;
/**
* This is a class to generate numbers for various purposes.
* @author Phil Reason
* @conceptionDate 9/6/13
* @version 1.1
* @revisionDate 9/8/13
*/
public class Generator {
/************** Constants *********************/
/**
* The single instance of Generator.
*/
public static final Generator READ_IN = getInstance();
private static Generator INSTANCE = null; // to contain the single instance
/******** Instance Vars: *******************/
private AtomicInteger counter; // construct an AtomicInteger
private int iDRange;
/************ Singleton SetUp ************/
/**
* non-public default constructor override.
*/
private Generator() {
super(); // unnessesary, but I always invoke super()
this.iDRange = 1000000; // the starting number to range increments
this.counter = new AtomicInteger(); // the AtomicInteger instance
} //END Generator()
/**
* Determine whether Generator already has an instance
* and return that instance.
*/
private static Generator getInstance() {
if (null == Generator.INSTANCE) { // upon first use...
Generator.INSTANCE = new Generator(); // construct the single instance
}
return Generator.INSTANCE; // return ony that instance
} // END Generator getInstance()
/**
* Generate non-repeating numbers. This can be useful for serializing when
* inherited serialization isn't useful or needed.
*
* Return the current count generation then increment the AtomicInteger.
* @ensure genID() >= 1000000 && genID() != genID() (never repeats a number)
*/
public int genID() {
return iDRange + counter.getAndIncrement(); // increments the sum of counter
} // END int genID()
}
Выходом из этой реализации является именно то, что мне было нужно, так как она работает на продолжительность жизни ординатуры памяти класса.Для этого свойства мне приходилось прогнозировать каждый приращение для JUnit между тестами, когда setUp() получает повтор - это не отменяет ссылку на статическую ссылку на класс из памяти. Для пакета, который я тестировал, это было на самом деле в мою пользу. Вот что я получил от выхода на этом последнем реализовать:
> Generator.READ_IN.GEN_ID
> 1000000
> Generator.READ_IN.GEN_ID
> 1000001
> Generator b = Generator.READ_IN
> b.GEN_ID
> 1000002
... and so on ...
В этом РЕАЛИЗАЦИИ AtomicInteger используется в качестве, как и в любом другом объекте с традиционным вызовом метода, хотя, как одноплодные. Мало того, что это работало для того, что мне было нужно, но я также смог избежать нарушения дизайна ООП. Мне понадобится больше практики, прежде чем я буду достаточно удобен, чтобы совершить статические фабрики. Еще раз спасибо вам три за то, что вы нашли время ответить на мой вопрос! ~ phil
Ваш код даже не будет скомпилирован, так как во втором случае вы пытаетесь вызвать метод экземпляра ('genID') из статического инициализатора, а в первом случае вы не видите полуточку на конец 'genID'. Мы не пытаемся найти ошибки в коде, который * не является * кодом, который вы используете. Пожалуйста, покажите короткую, но * полную * программу, демонстрирующую проблему. –
Я понял, что псевдокода будет достаточно, чтобы охватить сферу моего вопроса. У моего класса не было проблем с компиляцией в r/l, но спасибо за советы – ToFue
Но как бы вы ожидали, что мы увидим, что не так с вашим * реальным * кодом, когда мы не можем видеть этот код? В будущем, пожалуйста, * работайте над предоставлением короткой, но полной программы. Вам повезло, что на этот раз Питер смог дать совсем другое решение, но мы до сих пор не знаем, что было не так с вашим исходным кодом. –