Механизм Java assert позволяет отключить вставку утверждений, которые по существу не требуют затрат времени выполнения (кроме файла большего размера), если утверждения отключены.Но это может охватывать все ситуации.
Например, многие из коллекций Java имеют «отказоустойчивые» итераторы, которые пытаются обнаружить, когда вы используете их небезопасным способом.Но для этого требуется, чтобы как коллекция, так и сам итератор поддерживали дополнительное состояние, которое не потребовалось бы, если бы этих проверок не было.
Предположим, что кто-то хотел сделать что-то подобное, но разрешить отключение проверок и, еслиони отключены, он сохраняет несколько байтов в итераторе, а также еще несколько байтов в ArrayList, или как угодно.
В качестве альтернативы, предположим, что мы делаем какой-то пул объектов, который мы хотим иметьвключить и выключить во время выполнения;когда он выключен, он должен просто использовать сборку мусора в Java и не иметь места для подсчета ссылок, например так (обратите внимание, что написанный код очень неработающий):
class MyClass {
static final boolean useRefCounts = my.global.Utils.useRefCounts();
static {
if(useRefCounts)
int refCount; // want instance field, not local variable
}
void incrementRefCount(){
if(useRefCounts) refCount++; // only use field if it exists;
}
/**return true if ready to be collected and reused*/
boolean decrementAndTestRefCount(){
// rely on Java's garbage collector if ref counting is disabled.
return useRefCounts && --refCount == 0;
}
}
Проблема с приведенным выше кодом заключается в том, чтостатический бок не имеет смысла.Но есть ли какая-то хитрость с использованием маломощной магии, чтобы заставить что-то в этом духе работать?(Если разрешена мощная магия, ядерная опция - это сгенерировать две версии MyClass и договориться поставить правильную на пути к классам во время запуска.)