Java результаты выполнения программы

Язык программирования Java SE 8. Подробное описание.

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

Java является языком программирования общего назначения, ориентированным на параллельное выполнение и основанным на классах объектно-ориентированным языком. Он специально разрабатывался так, чтобы быть достаточно простым, так что многие программисты могут легко достичь высокой скорости работы.

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

Язык программирования Java — язык относительно высокого уровня, что проявляется, в частности, в том, что детали представления машинного кода в языке недоступны.

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

Язык не включает ни одной небезопасной конструкции, такой как доступ к массиву без проверки диапазонов индексирования, поскольку такие небезопасные конструкции могут приводить к неопределенному поведению программы.

Программа на языке Java обычно компилируется в набор команд байт-кода и бинарный формат, определенный в спецификации виртуальной машины Java The Java Virtual Machine Specification, Java SE 8 Edition.

Источник

Компиляция и исполнение Java приложений под капотом

Java-университет

Всем привет! Сегодня я хотел бы поделиться знаниями о том, что происходит под капотом JVM (Java Virtual Machine) после того, как мы запускаем написанное Java приложение. В наше время существуют моднейшие среды разработки, которые помогают не думать о внутреннем устройстве JVM, компиляции и выполнении Java-кода, из за чего новые разработчики могут упустить эти важные аспекты. В то же время, на собеседованиях часто задают вопросы касательно этой темы, из-за чего я и решил написать статью.

2. Компиляция в байт-код

Компиляция и исполнение Java приложений под капотом - 2

Начнем с теории. Когда мы пишем какое-либо приложение, мы создаем файл с расширением .java и помещаем в него код на языке программирования Java. Такой файл, содержащий код, понятный человеку, называется файлом с исходным кодом. После того, как файл с исходным кодом готов, нужно его выполнить! Но на стадии в нем содержится информация, понятная только человеку. Java — мультиплатформенный язык программирования. Это значит, что программы, написанные на языке Java, можно выполнять на любой платформе, где установлена специальная исполняющая система Java. Такая система называется Java Virtual Machine (JVM). Для того, чтобы перевести программу из исходного кода в код, понятный JVM, нужно её скомпилировать. Код, понятный JVM называется байт-кодом и содержит набор инструкций, которые в дальнейшем будет исполнять виртуальная машина. Для компиляции исходного кода в байт-код существует компилятор javac , входящий в поставку JDK (Java Development Kit). На вход компилятор принимает файл с расширением .java , содежащий исходный код программы, а на выходе выдает файл с расширением .class , содержащий байт-код, необходимый для исполнения программы виртуальной машиной. После того, как программа была скомпилирована в байт-код, она может быть выполнена с помощью виртуальной машины.

Читайте также:  Handle post request html

3. Пример компиляции и выполнения программы

Предположим, что у нас есть простая программа, содержащаяся в файле Calculator.java , которая принимает 2 численных аргумента командной строки и печатает результат их сложения:

Для того, чтобы скомпилировать эту программу в байт-код, воспользуемся компилятором javac в командной строке:

После компиляции на выходе мы получаем файл с байт-кодом Calculator.class , который мы можем исполнить при помощи установленной на нашем компьютере java-машины командой java в командной строке:

Заметим, что после названия файла были указаны 2 аргумента командной строки — числа 1 и 2. После выполнения программы, в командной строке выведется число 3. В примере выше у нас был простой класс, который живет сам по себе. Но что, если класс находится в каком либо пакете? Смоделируем такую ситуацию: создадим директории src/ru/javarush и поместим туда наш класс. Теперь он выглядит следующим образом (добавили имя пакета в начале файла):

 package ru.javarush; class Calculator < public static void main(String[] args)< int a = Integer.valueOf(args[0]); int b = Integer.valueOf(args[1]); System.out.println(a + b); >> 
 javac -d bin src/ru/javarush/Calculator.java 

В этом примере мы использовали дополнительную опцию компилятора -d bin , которая складывает скомпилированные файлы в директорию bin со структурой, аналогичной директории src , при этом директория bin должна быть создана заранее. Такой прием используется, чтобы не путать файлы с исходным кодом с файлами с байт-кодом. Перед запуском скомпилированной программы стоит пояснить понятие classpath . Classpath — это путь, относительно которого виртуальная машина будет искать пакеты и скомпилированные классы. Тоесть, таким образом мы говорим виртуальной машине какие директории в файловой системе являются корневыми для иерархии пакета Java. Classpath можно укзать при запуска программы с помощью флага -classpath . Запуск программы осуществляем с помощью команды:

 java -classpath ./bin ru.javarush.Calculator 1 2 

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

 ├── src │ └── ru │ └── javarush │ └── Calculator.java └── bin └── ru └── javarush └── Calculator.class 

4. Выполнение программы виртуальной машиной

Итак, мы запустили написанную программу. Но что же происходит в момент запуска скомпилированной программы виртуальной машиной? Для начала разберемся, что означают понятия компиляции и интерпретации кода. Компиляция — трансляция программы, составленной на исходном языке высокого уровня, в эквивалентную программу на низкоуровневом языке, близком машинному коду. Интерпретация — пооператорный (покомандный, построчный) анализ, обработка и тут же выполнение исходной программы или запроса (в отличие от компиляции, при которой программа транслируется без её выполнения). Язык Java обладает как компилятором ( javac ), так и интерпретатором, в роли которого выступает виртуальная машина, которая построчно преобразует байт-код в машинный код и тут же его исполняет. Таким образом, когда мы запускаем скомпилированную программу, виртуальная машина начинает её интерпретацию, то есть построчное преобразование байт-кода в машинный код, а так же его исполнение. К сожалению, чистая интерпретация байт-кода является довольно долгим процессом и делает язык java медленным в сравнении с его конкурентами. Дабы избежать этого, был введен механизм, позволяющий ускорить интерпретацию байт-кода виртуальной машиной. Этот механизм называется Just-in-time компиляцией (JITC).

Читайте также:  What can you do with javascript language

5. Just-in-time (JIT) компиляция

Простыми словами, механизм Just-In-Time компиляции заключается в следующем: если в программе присутствуют части кода, которые выполняются много раз, то их можно скомпилировать один раз в машинный код, чтобы в будущем ускорить их выполнение. После компиляции такой части программы в машинный код, при каждом следующем вызове этой части программы виртуальная машина будет сразу выполнять скомпилированный машинный код, а не интерпретировать его, что естественно ускорит выполнение программы. Ускорение работы программы достигается за счет увеличения потребления памяти (где-то же нам нужно хранить скомпилированный машинный код!) и за счет увеличения временных затрат на компиляцию во время исполнения программы. JIT компиляция — довольно сложный механизм, поэтому пройдемся по верхам. Всего существует 4 уровня JIT компиляции байт-кода в машинный код. Чем выше уровень компиляции, тем он сложнее, но и одновременно выполнение такого участка будет быстрее, чем участка с меньшим уровнем. JIT — компилятор самостоятельно решает, какой уровень компиляции задать для каждого фрагмента программы на основе того, как часто выполняется этот фрагмент. Под капотом JVM использует 2 JIT-компилятора — C1 и C2. C1 компилятор так же называется клиентским компилятором и способен скомпилировать код только до 3-его уровня. За 4-ый, самый сложны и быстрый уровень компиляции отвечает компилятор C2.

Компиляция и исполнение Java приложений под капотом - 3

Из вышесказанного можно сделать вывод о том, что для простых, клиентских приложений, выгоднее использовать компилятор C1, так как в этом случае нам важно как быстро стартует приложение. Серверные, долгоживущие приложения могут стартовать большее количество времени, однако в дальнейшем должны работать и выполнять свою функцию быстро — тут нам подойдет компилятор C2.

При запуске Java — программы на x32 версии JVM мы в ручную можем указать, какой режим мы хотим использовать, при помощи флагов -client и -server . При указании флага -client JVM не будет производить сложные оптимизации с байт-кодом, что ускорит время старта приложения и уменьшит количество потребляемой памяти. При указании флага -server приложение будет стартовать большее количество времени из-за сложных оптимизаций байт-кода и будет использовать больше памяти для хранения машинного кода, однако в дальнейшем работать такая программа будет быстрее. В x64 версии JVM флаг -client игнорируется и по умолчанию используется серверная конфигурация приложения.

Читайте также:  Html editor and mac

6. Заключение

Компилятор javac преобразует исходный код программы в байт-код, который может быть выполнен на любой платформе, на которой установлена виртуальная машина Java;

Для ускорения работы Java-приложений, JVM использует механизм Just-In-Time компиляции, который преобразует наиболее часто выполняемые участки программы в машинный код и хранит их в памяти.

Источник

Java результаты выполнения программы

Методы могут возвращать некоторое значение. Для этого применяется оператор return .

return возвращаемое_значение;

После оператора return указывается возвращаемое значение, которое является результатом метода. Это может быть литеральное значение, значение переменной или какого-то сложного выражения.

public class Program < public static void main (String args[])< int x = sum(1, 2, 3); int y = sum(1, 4, 9); System.out.println(x); // 6 System.out.println(y); // 14 >static int sum(int a, int b, int c) < return a + b + c; >>

В методе в качестве типа возвращаемого значения вместо void используется любой другой тип. В данном случае метод sum возвращает значение типа int , поэтому этот тип указывается перед названием метода. Причем если в качестве возвращаемого типа для метода определен любой другой, отличный от void , то метод обязательно должен использовать оператор return для возвращения значения.

При этом возвращаемое значение всегда должно иметь тот же тип, что значится в определении функции. И если функция возвращает значение типа int , то после оператора return стоит целочисленное значение, которое является объектом типа int . Как в данном случае это сумма значений параметров метода.

Метод может использовать несколько вызовов оператора return для возваращения разных значений в зависимости от некоторых условий:

public class Program < public static void main (String args[])< System.out.println(daytime(7)); // Good morning System.out.println(daytime(13)); // Good after noon System.out.println(daytime(18)); // Good evening System.out.println(daytime(2)); // Good night >static String daytime(int hour)< if (hour >24 || hour < 0) return "Invalid data"; else if(hour >21 || hour < 6) return "Good night"; else if(hour >= 15) return "Good evening"; else if(hour >= 11) return "Good after noon"; else return "Good morning"; > >

Здесь метод daytime возвращает значение типа String, то есть строку, и в зависимости от значения параметра hour возвращаемая строка будет различаться.

Выход из метода

Оператор return применяется для возвращаения значения из метода, но и для выхода из метода. В подобном качестве оператор return применяется в методах, которые ничего не возвращают, то есть имеют тип void :

public class Program < public static void main (String args[])< daytime(7); // Good morning daytime(13); // Good after noon daytime(32); // daytime(56); // daytime(2); // Good night >static void daytime(int hour)< if (hour >24 || hour < 0) return; if(hour >21 || hour < 6) System.out.println("Good night"); else if(hour >= 15) System.out.println("Good evening"); else if(hour >= 11) System.out.println("Good after noon"); else System.out.println("Good morning"); > >

Если переданное в метод datetime значение больше 24 или меньше 0, то просто выходим из метода. Возвращаемое значение после return указывать в этом случае не нужно.

Источник

Оцените статью