Psvm java что это
Лайфхаки IDEA
1. Автодополнение (Tab)
Например, у Intellij IDEA есть такая великолепная вещь, как автодополнение. Intellij IDEA разбирает и анализирует все файлы вашего проекта (включая все используемые библиотеки) и понимает, какие у вас есть классы, какие у классов есть методы и переменные. А потом использует всю эту информацию, чтобы помогать вам писать код.
Вы просто начинаете писать какое-нибудь слово, а она тут же вам предлагает подсказки, чтобы его закончить. Одна из самых часто используемых клавиш в автодополнении — это клавиша табуляции «Tab».
Например, вы хотите написать System. Для этого вам нужно написать Sys и нажать кнопку «Tab»: остальное IDEA закончит за вас.
Если вы после имени переменной поставили точку, то IDEA сначала определит, какой у этой переменной был тип, а затем предложит вам список методов, которые можно вызвать у этой переменной. Это очень удобно.
Или, например, вы хотите написать имя класса InputStreamReader. IntelliJ IDEA поможет вам сэкономить время: вы можете просто набрать три заглавные буквы — ISR ( I nput S tream R eader) и нажать Tab. И IDEA преобразует все написанное в InputStreamReader. Почти магия.
2. Live Templates: psvm, sout, psfs, fori
В IntelliJ IDEA есть тысячи вещей, за которые ее обожают профессиональные программисты, хотя и для новичков у нее тоже кое-что припасено. Например:
Метод main
Для этого нужно написать 4 буквы psvm и нажать Tab. А IDEA заменит «psvm» на « public static void main(String[] args) ». Магия.
Запомнить сочетание psvm очень легко — это сокращение от public static void main.
Также есть способ быстро написать System.out.println();
Для этого тоже нужно написать 4 буквы «sout» и нажать Tab. А IDEA заменит «sout» на « System.out.println(); »
Объявление текстовой константы
Есть способ быстро объявить переменную типа String (на уровне класса).
Для этого тоже нужно написать 4 буквы «psfs» и нажать Tab. А IDEA заменит «psfs» на « public static final String »
Запомнить тоже просто: psfs — это 4 буквы из p ublic s tatic f inal S tring
Есть аналогичное сокращение для любого типа данных. «psf» — public static final >
Цикл
Быстро написать цикл в IDEA можно с помощью команды fori + Tab. При этом IDEA заменит fori на код:
Вам останется только прописать максимальное значение, до которого должен меняться счетчик i.
Это может и не самые популярные вещи для Java-профессионалов, но вам, как новичку, они точно облегчат жизнь.
3. Оборачивание: Ctrl+Alt+T
Иногда в работе программиста возникают ситуации, когда хочется что-то сделать с уже написанным кодом. Для этого в Intellij IDEA есть специальная команда, которая позволяет «обернуть» написанный код чем-то еще.
Например, вы хотите выполнить какой-то код не один раз, а несколько. Логично сделать цикл и поместить код внутрь цикла. Можно, конечно, написать заголовок цикла, скобки вначале, скобки в конце. Скопировать нужный код внутрь цикла, а затем пройтись по всем строкам в теле цикла и сдвинуть их вправо.
Но можно поступить проще: обернуть уже готовый код в цикл, а все остальное Intellij IDEA сделает сама. Вам нужно будет сделать 3 вещи:
Пример меню в IDEA:
4. Стиль кода: Ctrl+Alt+L
И еще один полезный момент. Очень часто в результате копирования кода его выравнивание нарушается: где-то лишние пробелы, где-то их не хватает и т.д. Вроде бы и работающий код, а выглядит как черт знает что.
Чтобы ваш код всегда выглядел отлично, вам достаточно нажать 3 кнопки: Ctrl+Alt+L
Как только вы их нажмете, Intellij IDEA тут же сама отформатирует весь код текущего файла: где нужно — расставит пробелы и знаки табуляции. Будет не код, а конфетка.
Кстати, все «стили кода» полностью настраиваются в настройках IntelliJ IDEA:
Psvm java что это
There’s no practical difference. The version with the dots is using varargs.
See section 12.1.4 of the Java Language Specification.
Jaikiran Pai wrote: By the way, what’s PSVM?
public static void main
Jesper de Jong wrote: There’s no practical difference. The version with the dots is using varargs.
See section 12.1.4 of the Java Language Specification.
Thanks Jesper de Jong
Jaikiran Pai wrote: By the way, what’s PSVM?
public static void main
There are only two hard things in computer science: cache invalidation, naming things, and off-by-one errors
Jaikiran Pai wrote: By the way, what’s PSVM?
public static void main
This is why we ask that you Use Real Words. I’ve been on this site for about ten years, and have never seen anyone use «PVSM» before.
Everything happens for the first time.
Tarun Oohri wrote: Everything happens for the first time.
Anyway, I presume you’re here to get help; in which case, isn’t it in your interests to make your questions as easily understood as possible?
Tarun Oohri wrote: Everything happens for the first time.
Anyway, I presume you’re here to get help; in which case, isn’t it in your interests to make your questions as easily understood as possible?
I totally agree with you guys..I am new in here and this was the first time i used short hand. You all are much more experienced and full of knowledge..So, i have a great regard for all of you and i appreciate the way problems are being addressed here.
Tarun Oohri wrote: I totally agree with you guys..I am new in here and this was the first time i used short hand.
No probs. Asking questions well is a bit of a «black art».
One of the best pages I know on the subject is this one; and of course there’s also our HowToAskQuestionsOnJavaRanch page too.
There’s quite a bit of content in both, but they really are worth getting to know, because it helps both you and us.
Hello World из байт-кода для JVM
Скомпилируем простенькую программу выводящую «Hello World» и пройдемся по его структуре
Не думаю, что статья будет достаточно информативной для тех, кто поверхностно не знает как выглядит байт-код и как с ним работает JVM (например, хотя бы простейшие инструкции (знание об их существовании)).
На самом деле, это не так сложно. Достаточно использовать инструмент javap из JDK и рассмотреть дизассемблированный код.
А мы приступим к разбору самой структуры байт-кода для JVM
Очень полезной книгой для этого стала официальная спецификация JVM — The Java Virtual Machine Specification на сайте oracle
Для начала создадим простенькую программу:
Скомпилируем её командой javac Main.java и собственно сделаем дизассемблинг
Это просто представление байт-кода, которое человеку видеть легче, чем оригинальный байт-код, но сам он выглядит иначе:
С этим кодом мы и будем работать.
Но для начала нам нужно его отформатировать, чтобы не путаться что где находится, а байт-код, на самом деле, имеет вполне жесткую структуру:
Её вы можете найти в спецификации JVM Chapter 4.1 The ClassFile Structure
Тут все просто — слева указана размерность в байтах, а справа описание.
Разбирать байт-код мы будем в hexadecimal, где каждая цифра занимает 4 бита, а следовательно, на два байта — 4 цифры и на четыре байта — 8 цифр.
magic
minor_version, major_version
Это версии вашего class файла. Если мы назовем major_version M и minor_version m, то получаем версию нашего class файла как M.m
Сейчас я сразу буду приводить примеры из нашей программы «Hello World», чтобы посмотреть как они используются:
Его же мы можем видеть в дизассемблированном коде, но уже в десятичной системе счисления:
constant_pool_count
Здесь указывается количество переменных в пуле констант. При этом, если вы решили писать код на чистом байт-коде, то вам обязательно нужно следить за его значением, так как если вы укажете не то значение, то вся программа полетит к чертям (проверено!).
Также следует не забывать, что вы должны писать туда количество_переменных_в_пуле + 1
constant_pool[]
Каждый тип переменной в пуле констант имеет свою структуру:
Таблица с тэгами можно найти в спецификации Table 4.3 Constant pool tags
Собственно, вот табличка:
Constant Type | Value |
---|---|
CONSTANT_Class | 7 |
CONSTANT_Fieldref | 9 |
CONSTANT_Methodref | 10 |
CONSTANT_InterfaceMethodref | 11 |
CONSTANT_String | 8 |
CONSTANT_Integer | 3 |
CONSTANT_Float | 4 |
CONSTANT_Long | 5 |
CONSTANT_Double | 6 |
CONSTANT_NameAndType | 12 |
CONSTANT_Utf8 | 1 |
CONSTANT_MethodHandle | 15 |
CONSTANT_MethodType | 16 |
CONSTANT_InvokeDynamic | 18 |
Как ранее уже говорилось, каждый тип константы имеет свою структуру.
Вот, например, структура CONSTANT_Class :
Структура поля и метода:
Тут важно заметить, что разные структуры, могут иметь разную длину.
Рассмотрим часть нашего кода:
Итак, смотрим на структуру константы и узнаем, что первый байт отведен под тип константы. Здесь мы видим 0a (10) — а, следовательно, это CONSTANT_Methodref
Смотрим его структуру:
После одного байта для тэга, нам нужно еще 4 байта для class_index и name_and_type_index
Отлично, мы нашли одну из значений пула констант. Идем дальше. Смотрим, 09 — значит тип CONSTANT_Fieldref
Вам может показаться, что большинство типов имеет одинаковую форму, но это не так.
Например, структура следующего типа выглядит так, CONSTANT_String :
Все эти структуры можно посмотреть в Chapter 4.4 The Constant Pool
Теперь разберем, что значат типы внутри самого info
Это же мы можем видеть в дизассемблированном коде:
Также можно выделить представление чисел и строк.
Про представление чисел можно прочитать начиная с главы 4.4.4, а мы пока разберем лишь строки, так как числа пока не входят в программу Hello World
Собственно, вот так представляется строка:
Например, наш Hello World:
Разбирая весь пул констант байт-кода, получим:
Также, мы можем сравнить его с дизассемблированным кодом:
Тем самым проверив, что все совпадает, ведь по сути javap просто обрабатывает этот байт-код и показывает нам его в форматированном виде.
Пул констант нужен для инструкций. Например:
Подробнее обо всех типах в пуле констант можно узнать в Chapter 4.4 The Constant Pool
Идем дальше по структуре ClassFile
access_flags
Это битовая маска для свойств модификаторов
Flag Name | Value | Interpretation |
---|---|---|
ACC_PUBLIC | 0x0001 | Declared public ; may be accessed from outside its package. |
ACC_FINAL | 0x0010 | Declared final ; no subclasses allowed. |
ACC_SUPER | 0x0020 | Treat superclass methods specially when invoked by the invokespecial instruction. |
ACC_INTERFACE | 0x0200 | Is an interface, not a class. |
ACC_ABSTRACT | 0x0400 | Declared abstract ; must not be instantiated. |
ACC_SYNTHETIC | 0x1000 | Declared synthetic; not present in the source code. |
ACC_ANNOTATION | 0x2000 | Declared as an annotation type. |
ACC_ENUM | 0x4000 | Declared as an enum type. |
this_class
Должна содержать адрес на this класса. В нашем случае, она находится по адресу 5:
Следует заметить, что структуру этой переменной должна соответствовать CONSTANT_Class_info
super_class
То есть в этих ячейках указан name_index из структуры:
interfaces_count, fields_count
methods_count
Количество методов. Хоть и в коде мы видим один метод в классе, но, на самом деле, их два. Кроме main метода еще есть конструктор по умолчанию. Поэтому их количество равно двум, в нашем случае.
methods[]
Каждый элемент должен соответствовать структуре method_info описанной в Chapter 4.6 Methods
В нашем байт-коде (отформатированном, с комментариями) выглядит это так:
Разберем по-подробнее структуру методов:
access_flags
К слову, ACC_VARARGS здесь необязательный, в том плане, что, если бы мы
использовали String[] args вместо String… args, то этого флага бы не было
name_index
descriptor_index
Грубо говоря, это адрес указывающий на дескриптор метода. Этот дескриптор содержит тип возвращаемого значения и тип его сигнатуры.
Также, в JVM используются интерпретируемые сокращения:
BaseType Character | Type | Interpretation |
---|---|---|
B | byte | signed byte |
C | char | Unicode character code point in the Basic Multilingual Plane, encoded with UTF-16 |
D | double | double-precision floating-point value |
F | float | single-precision floating-point value |
I | int | integer |
J | long | long integer |
L ClassName ; | reference | an instance of class ClassName |
S | short | signed short |
Z | boolean | true or false |
[ | reference | one array dimension |
В общем случае это выглядит так:
Например, следующий метод:
Можно представить в виде
Далее, идут атрибуты, которые также имеют свою структуру.
Но сначала, как и всегда, идет его количество attributes_count
Затем сами атрибуты со структурой описанной в Chapter 4.7 Attributes
attribute_name_index
attribute_length
Содержит длину атрибута, не включая attribute_name_index и attribute_length
info
max_stack
Мне кажется, что имя этого атрибута может ввести в заблуждение из-за приставки max. На самом деле, это минимальный размер стека нужный для выполнения операции. Ну, это имя приобретает логику, если сказать, максимальный размер стека, который будет достигнут во время выполнения операции.
Упрощенно говоря, JVM выделит место для стека операндов. Там можно указывать значение, которое больше, чем нужно, но определение в этом атрибуте значения меньше, чем нужно приведет к ошибке.
max_locals
Максимальный размер локальных переменных
Ознакомится с локальными переменными можно либо в Mastering Java Bytecode at the Core of the JVM или в том же JVM Internals
code_length
Размер кода, который будет исполнятся внутри метода
code[]
Каждый код указывает на какую-то инструкцию. Таблицу соотношения optcode и команды с мнемоникой можно найти в википедии — Java bytecode instruction listings или в самой спецификации в конце книги
Для примера, возьмем наш конструктор:
Здесь мы можем найти наш код:
Ищем в таблице команды и сопоставляем:
Также описания этих команд можно найти здесь: Chapter 4.10.1.9. Type Checking Instructions
exception_table_length
Задает число элементов в таблице exception_table. У нас пока нет перехватов исключений поэтому разбирать его не будем. Но дополнительно можно почитать Chapter 4.7.3 The Code Attribute
exception_table[]
Имеет вот такую структуру:
attributes_count
Количество атрибутов в Code
attributes[]
Атрибуты, часто используются анализаторами или отладчиками.
Средства для работы с байт-кодом
Это немного не та тема, которая относится к данной статье, но все же косвенно связанная с ней.
Средств для работы с байт-кодом, на самом деле, достаточно много. Здесь я бы хотел рассмотреть Byte Code Engineering Library (BCEL) от Apache Commons.
Для начала, с помощью него мы может получить некоторые атрибуты байт-кода:
Помимо этого мы можем сгенерировать, изменить или дизассемблировать (например, в Jasmin) байт-код.
Парочку примеров можно найти в моем репозитории или в официальных примерах
Также, я уделил внимание и Jasmin. На самом деле, я не знаю, чем оно может быть полезно, но я её использовал при изучении механизма работы JVM с байт-кодом.
С помощью неё можно писать на упрощенном ассемблерном коде:
Вот мы и разобрали простую программку Hello World
Листинг байт-кода с комментариями можно найти на моем гисте: gist.github
Если есть ошибки прошу писать в комментариях или в сообщениях.
Разбор вопросов и ответов с собеседований на Java-разработчика. Часть 15
Java Core
9. В чем разница между статическим и динамическим связыванием в Java?
10. Можно ли использовать private или protected переменные в interface?
11. Что такое Classloader и для чего используется?
Bootstrap ClassLoader — базовый загрузчик, реализован на уровне JVM и не имеет обратной связи со средой выполнения, так как является частью ядра JVM и написан в машинном коде. Данный загрузчик служит родительским элементом для всех других экземпляров ClassLoader.
В основном отвечает за загрузку внутренних классов JDK, обычно rt.jar и других основных библиотек, расположенных в каталоге $ JAVA_HOME / jre / lib. У разных платформ могут быть разные реализации этого загрузчика классов.
Extension Classloader — загрузчик расширений, потомок класса базового загрузчика. Заботится о загрузке расширения стандартных базовых классов Java. Загружается из каталога расширений JDK, обычно — $ JAVA_HOME / lib / ext или любого другого каталога, упомянутого в системном свойстве java.ext.dirs (с помощью данной опции можно управлять загрузкой расширений).
System ClassLoader — системный загрузчик, реализованный на уровне JRE, который заботится о загрузке всех классов уровня приложения в JVM. Он загружает файлы, найденные в переменном окружении классов -classpath или -cp опции командной строки.
System Classloader пытается найти класс в своем кеше.
1.1. Если класс найден, загрузка успешно завершена.
1.2. Если класс не найден, загрузка делегируется к Extension Classloader-у.
Extension Classloader пытается найти класс в собственном кеше.
2.1. Если класс найден — успешно завершена.
2.2. Если класс не найден, загрузка делегируется Bootstrap Classloader-у.
Bootstrap Classloader пытается найти класс в собственном кеше.
3.1. Если класс найден, загрузка успешно завершена.
3.2. Если класс не найден, базовый Bootstrap Classloader попытается его загрузить.
4.1. Прошла успешно — загрузка класса завершена.
4.2. Не прошла успешно — управление передается к Extension Classloader.
5. Extension Classloader пытается загрузить класс, и если загрузка:
5.1. Прошла успешно — загрузка класса завершена.
5.2. Не прошла успешно — управление передается к System Classloader.
6. System Classloader пытается загрузить класс, и если загрузка:
6.1. Прошла успешно — загрузка класса завершена.
6.2. Не прошла успешно — генерируется исключение — ClassNotFoundException.
Тема загрузчиков классов обширна и ею не стоит пренебрегать. Чтобы ознакомиться с ней подробнее, советую прочесть эту статью, а мы не будем задерживаться и пойдем дальше.
12. Что такое Run-Time Data Areas?
PC Register — регистр ПК — локален для каждого потока и содержит адрес инструкции JVM, которую поток выполняет в данный момент.
JVM Stack — область памяти, которая используется как хранилище для локальных переменных и временных результатов. У каждого потока есть свой отдельный стек: как только поток завершается, этот стек также уничтожается. Стоит отметить, что преимуществом stack над heap является производительность, в то время как heap безусловно имеет преимущество в масштабе хранилища.
Native Method Stack — область данных для каждого потока, в которой хранятся элементы данных, аналогичные стеку JVM, для выполнения собственных (не Java) методов.
Heap — используется всеми потоками как хранилище которое содержит объекты, метаданные классов, массивы и т. д., которые создаются во время выполнения. Данная область создается при запуске JVM и уничтожается при завершении ее работы.
Method area — область метода — эта область времени выполнения общая для всех потоков и создается при запуске JVM. Он хранит структуры для каждого класса, такие как пул констант (Runtime Constant Pool — пул для хранения констант), код для конструкторов и методов, данные метода и т. д.
13. Что такое immutable object?
14. В чем особенность класса String?
Это самый популярный объект в Java, который применяют для разнообразных целей. По частоте использования он не уступает даже примитивным типам.
String — это immutable класс: при создании объекта данного класса его данные нельзя изменить (когда вы к некоторой строке добавляете + “другую строку”, как результат вы получите новую, третью строку). Неизменность класса String делает его потокобезопасным.
Класс String финализирован (имеет модификатор final ), поэтому его наследование невозможно.
У String есть свой пул строк, область памяти в heap, которая кеширует создаваемые строковые значения. В этой части серии, в 62 вопросе, я описывал строковой пул.