Как открыть файл с расширением class. Редактирование class файлов. Программы, открывающие файл CLASS

Новости 08.02.2019

Обычно при компиляции Java-файла получаются.class-файлы примерно того же размера, что и исходник. Меня заинтересовало, можно ли по небольшому исходнику сделать.class-файл, который больше, сильно больше исходника.

Можно поискать какие-то короткие конструкции языка, которые компилируются в длинные цепочки байткода, но линейный прирост меня не устраивал. Я сразу подумал про компиляцию finally-блоков: про неё уже писали на Хабре . Если вкратце, то для каждого finally-блока при непустом try-блоке создаётся минимум два варианта в байткоде: для случая нормального завершения try-блока и для случая завершения с исключением. В последнем случае исключение сохраняется в новую локальную переменную, выполняется код finally, затем исключение достаётся из локальной переменной и перебрасывается. А что если внутри finally снова разместить try-finally и так далее? Результат превзошёл все ожидания.

Я компилировал с помощью Oracle javac 1.7.0.60 и 1.8.0.25, результаты практически не отличались. Путь для исключения формируется даже в том случае, если в блоке try совсем ничего предосудительного. Например, присваивание целочисленной константы в локальную переменную - это две инструкции iconst и istore , ни про одну из них в спецификации не сказано, что они могут сгенерировать исключение. Так и будем писать:
class A {{ int a; try {a=0;} finally { try {a=0;} finally { try {a=0;} finally { try {a=0;} finally { try {a=0;} finally { try {a=0;} finally { try {a=0;} finally { try {a=0;} finally { try {a=0;} finally { try {a=0;} finally { try {a=0;} finally { try {a=0;} finally { a=0; }}}}}}}}}}}} }}
Добавление нового нетривиального кода в самый внутренний finally вызывает ошибку компиляции code too large, поэтому ограничимся таким. Если кто-то подзабыл, это у нас блок инициализации , который подклеивается к каждому конструктору. Для нашей задачи метод объявлять смысла нет.

Такой исходник занимает 336 байт, а получившийся class-файл растаращило до 6 571 429 байт, то есть в 19 557 раз (назовём это коэффициентом растаращивания). Даже при отключении всей отладочной информации с помощью -g:none class-файл весит 6 522 221 байт, что ненамного меньше. Посмотрим, что внутри с помощью утилиты javap .

Пул констант
Пул констант получился небольшой: всего 16 записей. По сути всё самое необходимое: имена атрибутов типа Code, имя класса, Java-файла, ссылка на конструктор родительского класса Object и т. д. При отключении отладочной информации исчезают три записи: имена атрибутов LineNumberTable, SourceFile и значение A.java для атрибута SourceFile.
Код
Код конструктора по умолчанию составил 64507 байт, почти упираясь в максимально допустимый предел. Начинается он с нормального выполнения:

Код

0: aload_0 1: invokespecial #1 // Method java/lang/Object."":()V 4: iconst_0 5: istore_1 6: iconst_0 7: istore_1 8: iconst_0 9: istore_1 10: iconst_0 11: istore_1 12: iconst_0 13: istore_1 14: iconst_0 15: istore_1 16: iconst_0 17: istore_1 18: iconst_0 19: istore_1 20: iconst_0 21: istore_1 22: iconst_0 23: istore_1 24: iconst_0 25: istore_1 26: iconst_0 27: istore_1 28: iconst_0 29: istore_1 30: goto 38


То есть вызывается конструктор родительского класса, а затем 13 раз записывается единица в первую локальную переменную. После этого начинается длинная цепочка goto, которая обходит мимо всех остальных копий finally: 30->38->58->104->198->388->770->1536->3074->7168->15358->31740->64506, а по адресу 64506 мы находим долгожданную инструкцию return.

В промежутках между этими goto всевозможные комбинации нормальных и исключительных завершений каждого блока try. Неожиданным оказалось то, что для каждого finally, обрабатывающего исключение, для хранения исключения создаётся новая локальная переменная, даже если блоки заведомо взаимоисключающие. Из-за этого коду требуется 4097 локальных переменных. Небольшая статистика по инструкциям:

  • iconst_1 - 8191 раз
  • istore_1 - 8191 раз
  • goto - 4095 раз
  • athrow - 4095 раз
  • astore_2/aload_2 - 1 раз
  • astore_3/aload_3 - 1 раз
  • astore/aload - 252 раза (локальные переменные с номерами от 4 до 255)
  • astore_w/aload_w - 3841 раз (локальные переменные с номерами больше 255)
Плюс один aload_0, один invokespecial и один return - итого 32765 инструкций. Желающие могут нарисовать граф потока управления и повесить на стенку.
Таблица исключений
Таблица исключений содержит записи вида (start_pc, end_pc, handler_pc, catch_type) и говорит виртуальной машине «если при выполнении инструкций от адреса start_pc до адреса end_pc произошло исключение типа catch_type, то передай управление на адрес handler_pc». В данном случае catch_type везде равен any, то есть исключения любого типа. Записей в таблице 8188 и занимает она примерно столько же, сколько и код - около 64 килобайт. Начало выглядит так:
from to target type 26 28 33 any 24 26 41 any 42 44 49 any 49 51 49 any 22 24 61 any
Таблица номеров строк
Таблица номеров строк - это отладочная информация, сопоставляющая адресам инструкций байткода номера строк в исходнике. В ней 12288 записей и чаще всего попадаются ссылки на строчку с самым внутренним finally. Занимает она около 48 килобайт.
StackMapTable
Куда же ушло всё остальное место? Его заняла таблица StackMapTable , которая необходима для верификации class-файла. Если совсем грубо, для каждой точки ветвления в коде эта таблица содержит типы элементов в стеке и типы локальных переменных в данной точке. Так как локальных переменных у нас очень много и точек ветвления тоже, размер этой таблицы растёт квадратично от размера кода. Если бы локальные переменные для исключений в непересекающихся ветках переиспользовались, их бы потребовалось всего 13 и таблица StackMapTable была бы куда скромнее по размерам.
Таращим дальше
Можно ли растаращить class-файл ещё сильнее? Конечно, можно раскопировать метод, содержащий вложенные try-finally. Но компилятор вполне может сделать это за нас. Вспомните, что блок инициализации приклеивается к каждому конструктору автоматически. Достаточно добавить в код много пустых конструкторов с разными сигнатурами. Здесь будьте осторожны, а то у компилятора кончится память. Ну вот так можно скромненько написать, упаковав код в одну строчку:

Class A{{int a;try{a=0;}finally{try{a=0;}finally{try{a=0;}finally{try{a=0;}finally{try{a=0;}finally{try{a=0;}finally{try{a=0;}finally{try{a=0;}finally{try{a=0;}finally{try{a=0;}finally{try{a=0;}finally{try{a=0;}finally{a=0;}}}}}}}}}}}}}A(){}A(int a){}A(char a){}A(double a){}A(float a){}A(long a){}A(short a){}A(boolean a){}A(String a){}A(Integer a){}A(Float a){}A(Short a){}A(Long a){}A(Double a){}A(Boolean a){}A(Character a){}}
Здесь у меня 16 конструкторов, исходник занимает 430 байт . После компиляции имеем 104 450 071 байт , коэффициент растаращивания составил 242 907 . И это не предел!

Файл формата CLASS открывается специальными программами. Чтобы открыть данный формат, скачайте одну из предложенных программ.

Чем открыть файл в формате CLASS

Расширение CLASS может быть представлено двумя основными исполнениями:

  • Формат CLASS (разработчик Oracle) относится к категории файлов, скомпилированных при помощи Java. Активируется двоичный байт-код расширения CLASS при инициализации Java Virtual Machine (JVM). Зачастую данный формат поддерживает совместную работу с файлами.

Выполняя команду javac, входящую в состав инсталляционного пакета JVM, можно получить расширение CLASS из Java-файлов. Некоторые интегрированные разновидности Java, например, Eclipse, поддерживают параллельную генерацию формата CLASS в процессе написания программного кода.

Ввиду того, что существует несколько модификаций JVM (включая версии 1.4-1.6), некоторые исполнения CLASS файлов могут не поддерживаться на определенных версиях JVM.

Отсутствие бинарного javac в комплексе Java Runtime Environment (JRE) не позволяет компилировать файлы CLASS, но не исключает возможности их фактического выполнения. JRE и JVM зачастую применяются как идентичные понятия, когда речь идет о платформе, запускающей Java приложения.

  • Расширение CLASS представляет собой исходник к (правообладателем лицензии является GNU Public). Gambas - полнофункциональный, объектно-ориентированный язык программирования, выполненный на базе интерпретатора BASIC.

Методы и средства программирования, а также архитектура языка во многом схожа с представлением Java.

В основе Gambas следующие программные модули:

  • компилятор;
  • транслятор;
  • архиватор;
  • скрипты;
  • рабочая программная область;
  • дополнительные компоненты и конструктивные элементы.

Программы для открытия CLASS файлов

Если CLASS расширение представляет собой категорию файлов, скомпилированную при помощи Java, для генерации и воспроизведения его на базе ОС Windows можно воспользоваться самыми разнообразными программными комплексами:

В данном представлении CLASS адаптирован и для платформы ОС Mac:

Расширение может быть открыто и на базе ОС Linux с применением все тех же программных плагинов

Самой частой причиной проблем с раскрытием файла CLASS является просто отсутствие соответствующих приложений, установленных на Вашем компьютере. В таком случае достаточно найти, скачать и установить приложение, обслуживающее файлы в формате CLASS - такие программы доступны ниже.

Поисковая система

Введите расширение файла

Помощь

Подсказка

Необходимо учесть, что некоторые закодированные данные из файлов, которые наш компьютер не читает, иногда можно просмотреть в Блокноте. Таким образом мы прочитаем фрагменты текста или числа - Стоит проверить, действует ли этот метод также в случае файлов CLASS.

Что сделать, если приложение со списка уже было установлено?

Часто установленное приложение должно автоматически связаться с файлом CLASS. Если это не произошло, то файл CLASS успешно можно связать вручную с ново установленным приложением. Достаточно нажать правой кнопкой мышки на файл CLASS, а затем среди доступных выбрать опцию "Выбрать программу по умолчанию". Затем необходимо выбрать опцию "Просмотреть" и отыскать избранное приложение. Введенные изменения необходимо утвердить с помощью опции "OK".

Программы, открывающие файл CLASS

Windows
Mac OS
Linux

Почему я не могу открыть файл CLASS?

Проблемы с файлами CLASS могут иметь также другую почву. Иногда даже установление на компьютере программного обеспечения, обслуживающего файлы CLASS не решит проблему. Причиной невозможности открытия, а также работы с файлом CLASS может быть также:

Несоответственные связи файла CLASS в записях реестра
- повреждение файла CLASS, который мы открываем
- инфицирование файла CLASS (вирусы)
- слишком маленький ресурс компьютера
- неактуальные драйверы
- устранение расширения CLASS из реестра системы Windows
- незавершенная установка программы, обслуживающей расширение CLASS

Устранение этих проблем должно привести к свободному открытию и работе с файлами CLASS. В случае, если компьютер по-прежнему имеет проблемы с файлами, необходимо воспользоваться помощью эксперта, который установит точную причину.

Мой компьютер не показывает расширений файлов, что сделать?

В стандартных установках системы Windows пользователь компьютера не видит расширения файлов CLASS. Это успешно можно изменить в настройках. Достаточно войти в "Панель управления" и выбрать "Вид и персонализация". Затем необходимо войти в "Опции папок", и открыть "Вид". В закладке "Вид" находится опция "Укрыть расширения известных типов файлов" - необходимо выбрать эту опцию и подтвердить операцию нажатием кнопки "OK". В этот момент расширения всех файлов, в том числе CLASS должны появится сортированные по названию файла.



Рекомендуем почитать

Наверх