Цель состоит в том, чтобы написать код Java, который обнаруживает версию JVM, полагаясь на изменения совместимости, побочные эффекты, ошибки и / или неопределенное поведение, которое работает в одной версии и другим способом в другой версии. Кроме того, код должен быть хотя бы немного читабельным, не жертвуя пробелами и разборчивыми именами переменных.
Для обеспечения этой цели, точные формальные правила:
Код должен быть написан на Java и должен выводить версию JRE, в которой он работает.
Код не должен использовать какой-либо JDK или JRE API, предоставленный специально для определения версии Java или который предоставляет версию JDK или JRE бесплатно.
Код не должен использовать отражение.
Код требуется только для работы в Hotspot Java SE 5, 6 и 7, но может работать и в других JVM.
Код не должен использовать сторонние библиотеки в пути к классам.
Код не должен запускать любой другой процесс, Java или нет.
Код не должен использовать переменные среды.
Код не должен искать файловую систему в поисках уже существующих файлов или папок.
Код должен содержаться в одном файле и вызываться через
public static void main(String[] args)
илиpublic static void main(String... args)
.Код не должен использовать какой-либо непубличный API, присутствующий в JRE.
Код не должен генерировать никаких NoClassDefFoundError, NoSuchMethodError, ClassNotFoundException или NoSuchMethodException во время его выполнения.
Код должен работать в системе, отключенной от Интернета или от любой локальной сети.
Вы должны предоставить объяснение того, почему он ведет себя так или иначе в версии и в другой версии.
счет
Для измерения наилучшего решения используется метод max (n / s), где n - это количество различных версий Java, обнаруженных без нарушения любого из этих правил (по крайней мере, версии 5, 6 и 7), а s - количество лексических токенов. в решении.
источник
Ответы:
6/102 = 0,0588
Обнаруживает 6 версий. Имеет 102 лексических маркеров (вниз от 103, после того, как я удалил
public
вpublic class
).Java 1.1 представила кодировки символов и криптографические алгоритмы для Java. Более поздние версии добавили больше кодировок и алгоритмов. Эта программа пытается использовать кодировки и алгоритмы, пока не поймает исключение. Я ожидаю, что бросит отсутствующую кодировку и бросит
java.io.UnsupportedEncodingException
отсутствующий алгоритмjava.security.NoSuchAlgorithmException
.У меня был старый PowerPC Macintosh с четырьмя старыми версиями Java. У моего компьютера с OpenBSD есть еще две версии, поэтому я протестировал эти шесть версий:
Эта программа также может работать в JamVM 1.5.4 и gcj 4.8.2 для OpenBSD, но не идентифицирует их как различные реализации. Он печатает только "Java 5".
Mac OS Runtime для Java
Благодаря «Пишите один раз, запускайте везде!», Я могу написать эту программу один раз, скомпилировать ее один раз и запустить один GuessVersion.class на всех восьми виртуальных машинах. Мне нужен компилятор для Java 1.1, самой старой версии в моей коллекции.
Мой компилятор -
javac
инструмент из MRJ SDK 2.2. Поскольку у Classic Mac OS не было командной строки,javac
это довольно графический инструмент, в котором я выбираю файлы и параметры и нажимаю «Сделать Javac». После того, как я отредактировал свой код, я просто снова нажимаю «Сделать Javac».Самый простой способ запустить GuessVersion.class - открыть его в JBindery, другом инструменте из MRJ SDK 2.2. Среда выполнения - MRJ 2.2.6, реализация Java 1.1.8.
источник
Я не уверен, каков мой счет, потому что это зависит от того, что именно вы считаете лексическим токеном, но я стараюсь максимально злоупотреблять этой системой подсчета длинной строкой ...
Это также зависит от того, считаете ли вы это идентифицирующим 7 различными версиями или 16 ... (оно может быть тривиально расширено до 190).
Он работает, пытаясь определить интерфейс в пользовательском загрузчике классов с нисходящими номерами основных версий формата класса. Первый, который не выбрасывает,
java.lang.UnsupportedClassVersionError
соответствует версии виртуальной машины.источник
String... args
.protected Class loadClass(String name, boolean resolve) { return Object.class; }
. В текущих документах API не упоминается, как это был абстрактный метод до Java 1.2. Я возвращаю Object.class, потому что метод получает один вызов для «java.lang.Object».Алгоритм интернирования изменился между Java 6 и 7. Https://stackoverflow.com/a/7224864/540552
XMLGregorianCalendar.equals (null) использовался для создания исключения NullPointerException в java 5, но это было исправлено в java 6. См. Http://bugs.sun.com/view_bug.do?bug_id=6285370
10096928785 жетонов здесь. Спасибо Питеру Тейлору за сокращение 7 жетонов.источник
DatatypeConfigurationException
он не будет брошен.int a
но сразу инициализировать, чтобыif
блок стал пустым. Отмените условие, удалите else и используйте--
вместо прямого присваиванияa
.