Я рекомендовал бы запустить путем рассмотрения раздела 3.4.2 из Donald Knuth Получисловые Алгоритмы .
, Если Ваши массивы являются большими, существуют более эффективные алгоритмы в главе 3 Принципы Генерации случайных переменных John Dagpunar. Если Ваши массивы не являются ужасно большими, или Вы не обеспокоены отжиманием как можно большей эффективности, более простые алгоритмы в Knuth прекрасны, вероятно.
Поле , созданное компилятором, которое связывает локальный внутренний класс с блоком локальная переменная или параметр ссылочного типа.
См. Также The JavaTM Virtual Machine Specification (§4.7.6)
или Синтетический класс на Java .
assert
инструкция JDK 1.8 тематическое исследование
Оператор assert
является примером конструкции, которая генерирует поле static synthetic
в Oracle JDK 1.8.0_45:
public class Assert {
public static void main(String[] args) {
assert System.currentTimeMillis() == 0L;
}
}
в основном компилируется в:
public class Assert {
// This field is synthetic.
static final boolean $assertionsDisabled =
!Assert.class.desiredAssertionStatus();
public static void main(String[] args) {
if (!$assertionsDisabled) {
if (System.currentTimeMillis() != 0L) {
throw new AssertionError();
}
}
}
}
Это можно проверить с помощью:
javac Assert.java
javap -c -constants -private -verbose Assert.class
, который содержит:
static final boolean $assertionsDisabled;
descriptor: Z
flags: ACC_STATIC, ACC_FINAL, ACC_SYNTHETIC
Синтетическое поле генерируется так, что Java нужно вызывать Assert.class.desiredAssertionStatus()
только один раз во время загрузки, а затем кэшировать результат там.
См. Также: https://stackoverflow.com/a/29439538/895245 для более подробного объяснения.
Обратите внимание, что это синтетическое поле может генерировать конфликты имен с другими полями, которые мы можем определить. Например, следующее не удается скомпилировать в Oracle JDK 1.8.0_45:
public class Assert {
static final boolean $assertionsDisabled = false;
public static void main(String[] args) {
assert System.currentTimeMillis() == 0L;
}
}
Единственное, что «мешает», - это соглашение об именовании, не использующее доллары в ваших идентификаторах. См. Также: Когда мне следует использовать символ доллара ($) в имени переменной?
Бонус:
static final int $assertionsDisabled = 0;
будет работать, поскольку в отличие от Java байт-код допускает несколько полей с одним и тем же именем, но с разными типами: Переменные с одинаковым именем, но с другим типом