What is a program, and why do we need a program?
Technically speaking, a program is just a set of instructions. So can we call any set of instructions as a program? No. These steps are not understandable by the computer. To make a computer understand, we write these sets of instructions as a program, basically a syntax that computers can understand.
Now since the computer only understands the language of programs, any instruction we give to the computer is basically telling a computer to run a specific program. Technically it informs the OS operating system to execute the program. Without OS, you cannot execute a program as it operates the system. There are multiple operating systems available, like Windows, Unix, Linux, Mac, DOS, etc..
The need for compilers and interpreters
To communicate with a computer, we use the English language, and the language that the computer understands is Machine Language. Now how do we communicate?
We write a program using high-level languages. In other words, languages like Java, C, C++, etc. This language is understandable by humans, not by computers. Source Code is the piece of code we write to execute on a machine. The computer understands machine code, i.e., data in binary form. The binary data can contain only 0 and 1 as its value.
Let’s say we use Java programming language. But to write a program in Java also, we use English itself. And the computer wants data in 0 and 1. Here is where a compiler and interpreter comes to convert our source code into machine code.
It is a medium that can convert our English language into computer understandable machine language.
Compilation Process
The basic compilation process goes through six phases, as shown below.
- Lexical Analysis
- In this phase, it scans the program (source code) character by character from left to right to convert it and produce a sequence of tokens.
- In this example, y, x, and 30 are identified as tokens.
- Syntax Analysis
- This phase constructs a structure using a series of tokens from the previous scanner, which is nothing but a parse tree.
- It will create a structure, using an operator as a parent node and identifiers as a child node. Basically, it determines if it follows a specific format or not.
- Semantic Analysis
- This phase ensures that the program has a well-defined meaning by checking the semantic consistency of the code. Type mismatches, incompatible operands, improper arguments, an undeclared variable, all these things are verified here.
- In our example, since x and y are floating-point numbers (decimal values) and 30 is an integer, we have a type mismatch. Hence, it will convert 30 inttofloat before performing any calculation.
- Intermediate Code Generation
- Intermediate code is the one that holds the values it computes during the compilation process. Eventually, it helps the translation of intermediate code to the target language.
- It will take temporary variables t1 and t2 to assign computed values and assign it back to the final result.
- Code Optimizer
- In this phase, it removes the unused code to speed up the execution of the program.
- Basically, it performs functions like –
- Speed up the execution of the target program
- Remove the unnecessary and unreachable code.
- Optimize the code
- So in our example, it will remove all the temporary variables and arrange the statement as id1 = id2 * 30.0
- Code Generator
- This phase will allocate storage, i.e., memory locations and registers, and generate relocatable machine code. The code generated in this phase takes input, executes it, and generates output.
- Registers are a type of temporary storage area in the computer memory that helps store any data or instructions by the CPU.
- Our example is performing three register operations – LDF, MULF, STF to load, multiply and store floating-point data.
- First, it will load identifier2, i.e., x in register1; then, it will multiply the value in register1 with floating-point 30.0 and store it back in register1, then finally store the value present in register1 into identifier 1, i.e., y.
How is an interpreter different from the compiler?
As a compiler, an interpreter is also a translator. It also takes a high-level language as input and then converts it into machine language. However, what it does differently than the compiler is that it executes the code immediately as it translates it.
In simple words, it will translate only a piece or line of code at a time, and as soon as it finishes translating, it will take the translated code and run it immediately. While what the compiler does is first translate the entire code and then execute.
Due to this, the interpreter displays the error as it runs, while the compiler displays all errors after compilation is done, i.e., all at once. Hence, the speed of execution of code is faster in the compiler than in an interpreter.
Java Development Kit
Source code is what we write using high-level languages like Java, C, C++, etc. Byte Code is present in the format of 0 and 1 but is non-runnable code, meaning you cannot run byte code directly.
Now java has something called JDK, which is the Java Development Kit. This kit contains some tools to develop and test Java programs. That is why we need to download and install JDK first to the compiler and run java programs.
Now, what comes along with this JDK? We get a JRE Java Runtime Environment, which provides resources and libraries to OS to execute the program and contains JIT compiler and other dev tools. JIT is Just in time compiler, which converts the byte code into understandable instructions at runtime that the processor executes directly. In other words, the JIT compiler converts byte code into machine code. Machine Code is also in binary format 0 and 1, but it is runnable and CPU executes it directly. Now inside JRE, we have JVM and some libraries. Java Virtual Machine is an engine or a virtual machine that calls the main method to run the java application.
So all these resources needed for java execution JVM, JRE, JIT compiler all comes under a package called JDK. So when we install JDK, all these are set up on our system by default to make it ready to execute java programs.
Compilation and Execution in Java
The commands used to compile and execute a java program –
javac eg.java
java eg
If you are trying to compile a java file outside its folder, you need to provide the classpath, which tells the compiler where your classes and packages are located. Something like this: java -classpath ;. <fileName>. When you want to execute a file outside its folder or from any other folder, you will need classpath to tell the compiler which files you want to run and where is its class file located.
To give any input to the program from the command prompt, we use command-line arguments. You can provide arguments like this: java <classname> <arguments>
Entry Point Function
The JVM controls the execution of all the programs, also calls the main method to start the execution. So this main method is nothing but the entry-point function.
- public is the access to the main method; it means this method can be called outside the class.
- static is the nature of the main method; it means this method can be called without even creating an object of the class that contains the main method. In other words, JVM directly calls the main method; we don’t create an object of its class to call this function.
- void is the method return type, i.e., it indicates that the main method does not return anything. Other return types are int, String, float, etc. If we don’t want to return anything, we use void as the return type.
- main is the method name since when we compile by writing javac class name, JVM will search for the main method in that class whose access is public, nature is static, the return type is void, and argument type is a String array.
- String args is the string array that we pass as an argument to the main function.
public static void main(String args[]){
System.out.println("Hello World!");
}
Important note
Unlike C++, in java, if a class doesn’t possess the main function, it still compiles the code. And if several java classes contain the main function, the code will still be compiled because execution is done based on a class’s main function whose name is given to the JVM.
Why is Java Platform Independent?
The bytecode generated after compilation is distributed and executed on different operating systems. So the bytecode is nothing but the compiled code. As written, Java is not platform-independent; Java compiled code is platform-independent. The compiled code, when placed on a different OS, and you try to execute, the JVM present on that OS will generate its machine code and run it on your machine/ your OS. However, that is not the case with other programming languages like C; you cannot compile it on one machine and execute it on another. So that is one big advantage of using Java Programming languages.
Explain JDK, JRE, JVM.
JDK is the Java Development Kit that contains some tools and libraries to help us develop and test our Java programs. That is why we need to download and install JDK first to compile and run java programs.
JDK comes along with a JRE Java Runtime Environment, which provides resources and libraries to OS to execute the program and contains JIT compiler and other dev tools. JIT is Just in time compiler, which converts the byte code into understandable instructions at runtime that can be sent to the processor directly for execution. In other words, the JIT compiler converts byte code into machine code. Machine Code is also in binary format 0 and 1, but it is runnable and CPU executes it directly. Now inside JRE, we have JVM and some libraries. Java Virtual Machine is an engine or a virtual machine that calls the main method to run the java application.
So all these resources needed for java execution JVM, JRE, JIT compiler all comes under a package called JDK. So when we install JDK, all these are set up on our system by default to make it ready to execute java programs.
Why Java is platform-independent?
It is inappropriate to say that Java is platform-independent. The truth is Java compiled code is platform-independent. The compiled code can be placed on a different OS to execute, not the source code. The JVM present on that OS will generate its machine code and run it on that machine/ your OS.
Why is Java not 100% Object-oriented?
Java does not just work on complex data types i,e, objects but also on primitive data types. That is the reason it’s not 100% Object Oriented.
What is the JIT compiler in Java?
JIT is Just in time compiler, which converts the byte code into understandable instructions at runtime that is send to the processor directly for execution. In other words, the JIT compiler converts byte code into machine code.
What is “public static void main()” in Java?
Here, ‘public’ is access, ‘static’ is the nature, ‘void’ is the return type and ‘main’ is the method. This main method is nothing but an entry-point function. The JVM controls the execution of all the programs, also calls the main method to start the execution.