Blog

  • Numbers

    Numbers in Fortran are represented by three intrinsic data types −

    • Integer type
    • Real type
    • Complex type

    Integer Type

    The integer types can hold only integer values. The following example extracts the largest value that could be hold in a usual four byte integer −

    program testingInt
    implicit none
    
       integer :: largeval
       print *, huge(largeval)
       
    end program testingInt

    When you compile and execute the above program it produces the following result −

    2147483647
    

    Please note that the huge() function gives the largest number that can be held by the specific integer data type. You can also specify the number of bytes using the kind specifier. The following example demonstrates this −

    program testingInt
    implicit none
    
       !two byte integer
       integer(kind = 2) :: shortval
       
       !four byte integer
       integer(kind = 4) :: longval
       
       !eight byte integer
       integer(kind = 8) :: verylongval
       
       !sixteen byte integer
       integer(kind = 16) :: veryverylongval
       
       !default integer 
       integer :: defval
    
        
    print *, huge(shortval) print *, huge(longval) print *, huge(verylongval) print *, huge(veryverylongval) print *, huge(defval) end program testingInt

    When you compile and execute the above program it produces the following result −

    32767
    2147483647
    9223372036854775807
    170141183460469231731687303715884105727
    2147483647
    

    Real Type

    It stores the floating point numbers, such as 2.0, 3.1415, -100.876, etc.

    Traditionally there were two different real types : the default real type and double precision type.

    However, Fortran 90/95 provides more control over the precision of real and integer data types through the kind specifier, which we will study shortly.

    The following example shows the use of real data type −

    program division   
    implicit none
    
       ! Define real variables   
       real :: p, q, realRes 
       
       ! Define integer variables  
       integer :: i, j, intRes  
       
       ! Assigning  values   
       p = 2.0 
       q = 3.0    
       i = 2 
       j = 3  
       
       ! floating point division
       realRes = p/q  
       intRes = i/j
       
       print *, realRes
       print *, intRes
       
    end program division  

    When you compile and execute the above program it produces the following result −

    0.666666687    
    0
    

    Complex Type

    This is used for storing complex numbers. A complex number has two parts : the real part and the imaginary part. Two consecutive numeric storage units store these two parts.

    For example, the complex number (3.0, -5.0) is equal to 3.0 – 5.0i

    The generic function cmplx() creates a complex number. It produces a result who’s real and imaginary parts are single precision, irrespective of the type of the input arguments.

    program createComplex
    implicit none
    
       integer :: i = 10
       real :: x = 5.17
       print *, cmplx(i, x)
       
    end program createComplex

    When you compile and execute the above program it produces the following result −

    (10.0000000, 5.17000008)
    

    The following program demonstrates complex number arithmetic −

    program ComplexArithmatic
    implicit none
    
       complex, parameter :: i = (0, 1)   ! sqrt(-1)   
       complex :: x, y, z 
       
       x = (7, 8); 
       y = (5, -7)   
       write(*,*) i * x * y
       
       z = x + y
       print *, "z = x + y = ", z
       
       z = x - y
       print *, "z = x - y = ", z 
       
       z = x * y
       print *, "z = x * y = ", z 
       
       z = x / y
       print *, "z = x / y = ", z 
       
    end program ComplexArithmatic

    When you compile and execute the above program it produces the following result −

    (9.00000000, 91.0000000)
    z = x + y = (12.0000000, 1.00000000)
    z = x - y = (2.00000000, 15.0000000)
    z = x * y = (91.0000000, -9.00000000)
    z = x / y = (-0.283783793, 1.20270276)
    

    The Range, Precision and Size of Numbers

    The range on integer numbers, the precision and the size of floating point numbers depends on the number of bits allocated to the specific data type.

    The following table displays the number of bits and range for integers −

    Number of bitsMaximum valueReason
    649,223,372,036,854,774,807(2**63)–1
    322,147,483,647(2**31)–1

    The following table displays the number of bits, smallest and largest value, and the precision for real numbers.

    Number of bitsLargest valueSmallest valuePrecision
    640.8E+3080.5E–30815–18
    321.7E+380.3E–386-9

    The following examples demonstrate this −

    program rangePrecision
    implicit none
    
       real:: x, y, z
       x = 1.5e+40
       y = 3.73e+40
       z = x * y 
       print *, z
       
    end program rangePrecision

    When you compile and execute the above program it produces the following result −

    x = 1.5e+40
    
          1
    Error : Real constant overflows its kind at (1) main.f95:5.12: y = 3.73e+40
           1
    Error : Real constant overflows its kind at (1)

    Now let us use a smaller number −

    program rangePrecision
    implicit none
    
       real:: x, y, z
       x = 1.5e+20
       y = 3.73e+20
       z = x * y 
       print *, z
       
       z = x/y
       print *, z
       
    end program rangePrecision

    When you compile and execute the above program it produces the following result −

    Infinity
    0.402144760   
    

    Now let’s watch underflow −

    Live Demo

    program rangePrecision
    implicit none
    
       real:: x, y, z
       x = 1.5e-30
       y = 3.73e-60
       z = x * y 
       print *, z
       
       z = x/y
       print *, z
    
    end program rangePrecision

    When you compile and execute the above program it produces the following result −

    y = 3.73e-60
    
           1
    Warning : Real constant underflows its kind at (1) Executing the program.... $demo  0.00000000E+00 Infinity

    The Kind Specifier

    In scientific programming, one often needs to know the range and precision of data of the hardware platform on which the work is being done.

    The intrinsic function kind() allows you to query the details of the hardware’s data representations before running a program.

    program kindCheck
    implicit none
       
       integer :: i 
       real :: r 
       complex :: cp 
       print *,' Integer ', kind(i) 
       print *,' Real ', kind(r) 
       print *,' Complex ', kind(cp) 
       
    end program kindCheck

    When you compile and execute the above program it produces the following result −

    Integer 4
    Real 4
    Complex 4
    

    You can also check the kind of all data types −

    Live Demo

    program checkKind
    implicit none
    
       integer :: i 
       real :: r 
       character :: c 
       logical :: lg 
       complex :: cp 
       
       print *,' Integer ', kind(i) 
       print *,' Real ', kind(r) 
       print *,' Complex ', kind(cp)
       print *,' Character ', kind(c) 
       print *,' Logical ', kind(lg)
       
    end program checkKind

    When you compile and execute the above program it produces the following result −

    Integer 4
    Real 4
    Complex 4
    Character 1
    Logical 4
    
  • Environment Setup

    Set Up Your Java Development Environment

    If you want to set up your own environment for Java programming language, then this tutorial guides you through the whole process. Please follow the steps given below to set up your Java environment.

    Java SE is available for download for free. To download click here, please download a version compatible with your operating system.

    Follow the instructions to download Java, and run the .exe to install Java on your machine. Once you have installed Java on your machine, you would need to set environment variables to point to correct installation directories.

    Setting Up the Environment Path for Windows 2000/XP

    Assuming you have installed Java in c:\Program Files\java\jdk directory. Below are the steps to set up the Java environment path for Windows 2000/XP:

    • Right-click on ‘My Computer’ and select ‘Properties’.
    • Click on the ‘Environment variables’ button under the ‘Advanced’ tab.
    • Now, edit the ‘Path’ variable and add the path to the Java executable directory at the end of it. For example, if the path is currently set to C:\Windows\System32, then edit it the following way
      C:\Windows\System32;c:\Program Files\java\jdk\bin.

    Setting Up the Environment Path for Windows 95/98/ME

    Assuming you have installed Java in c:\Program Files\java\jdk directory. Below are the steps to set up the Java environment path for Windows 95/98/ME:

    • Edit the ‘C:\autoexec.bat’ file and add the following line at the end −
      SET PATH=%PATH%;C:\Program Files\java\jdk\bin

    Setting Up the Environment Path for Linux, UNIX, Solaris, FreeBSD

    Environment variable PATH should be set to point to where the Java binaries have been installed. Refer to your shell documentation if you have trouble doing this.

    For example, if you use bash as your shell, then you would add the following line at the end of your .bashrc −

    export PATH=/path/to/java:$PATH’

    Online Java Compiler

    We have set up the Java Programming environment online, so that you can compile and execute all the available examples online. It gives you confidence in what you are reading and enables you to verify the programs with different options. Feel free to modify any example and execute it online.

    Try the following example using Run & Edit button available at the top right corner of the above sample code box −

    publicclassMyFirstJavaProgram{publicstaticvoidmain(String[]args){System.out.println("Hello World");}}

    For most of the examples given in this tutorial, you will find a Run & Edit option in our website code sections at the top right corner that will take you to the Online Java Compiler. So just make use of it and enjoy your learning.

    Popular Java Editors

    To write Java programs, you need a text editor. There are even more sophisticated IDEs available in the market. The most popular ones are briefly described below −

    • Notepad − On Windows machine, you can use any simple text editor like Notepad (recommended for this tutorial) or WordPad. Notepad++ is also a free text editor which enhanced facilities.
    • Netbeans − It is a Java IDE that is open-source and free which can be downloaded from www.netbeans.org/index.html.
    • Eclipse − It is also a Java IDE developed by the Eclipse open-source community and can be downloaded from www.eclipse.org.

    IDE or Integrated Development Environment, provides all common tools and facilities to aid in programming, such as source code editor, build tools and debuggers etc.

  • Hello World Program

    Printing “Hello World” on the output screen (console) is the first program in Java and other programming languages. This tutorial will teach you how you can write your first program (print “Hello World” program) in Java programming.

    Java program to print “Hello World”

    Java program to print “Hello World” is given below:

    publicclassMyFirstJavaProgram{/* This is my first java program.
    
    * This will print 'Hello World' as the output
    */publicstaticvoidmain(String&#91;]args){System.out.println("Hello World");// prints Hello World}}</code></pre>

    Steps to Write, Save, and Run Hello World Program

    Let's look at how to save the file, compile, and run the program. Please follow the subsequent steps −

    • Open notepad and add the code as above.
    • Save the file as − "MyFirstJavaProgram.java".
    • Open a command prompt window and go to the directory where you saved the class. Assume it's C:\.
    • Type 'javac MyFirstJavaProgram.java' and press enter to compile your code. If there is no error in your code, the command prompt will take you to the next line (Assumption − The path variable is set. Learn: Java Envionment Setup).
    • Now, type 'java MyFirstJavaProgram' to run your program.
    • You will be able to see "Hello World" printed on the screen.

    Output

    C:\> javac MyFirstJavaProgram.java
    C:\> java MyFirstJavaProgram
    Hello World
    

    Explanation of Hello World Program

    As we've successfully printed Hello World on the output screen. Let's understand the code line by line.

    1. Public Main Class

    publicclassMyFirstJavaProgram{

    This line is creating a new class MyFirstJavaProgram and being public, this class is to be defined in the same name file as MyFirstJavaProgram.java. This convention helps Java compiler to identify the name of public class to be created before reading the file content.

    2. Comment Section

    /* This is my first java program.
    * This will print 'Hello World' as the output
    */

    These lines being in /* */ block are not considered by Java compiler and are comments. A comment helps to understand program in a better way and makes code readable and understandable.

    3. Public Static Void Main

    publicstaticvoidmain(String[]args){

    This line represents the main method that JVM calls when this program is loaded into memory. This method is used to execute the program. Once this method is finished, program is finished in single threaded environment.

    4. Keywords Used

    Let's check the purpose of each keyword in this line.

    • public − defines the scope of the main method. Being public, this method can be called by external program like JVM.
    • static − defines the state of the main method. Being static, this method can be called by external program like JVM without first creating the object of the class.
    • void − defines the return type of the main method. Being void, this method is not returning any value.
    • main − name of the method
    • String []args − arguments passed on command line while executing the java command.

    5. System.out.println() Method

    System.out.println("Hello World");// prints Hello World

    System.out represents the primary console and its println() method is taking "Hello World" as input and it prints the same to the console output.

  • Loops

    There may be a situation, when you need to execute a block of code several number of times. In general, statements are executed sequentially : The first statement in a function is executed first, followed by the second, and so on.

    Programming languages provide various control structures that allow for more complicated execution paths.

    A loop statement allows us to execute a statement or group of statements multiple times and following is the general form of a loop statement in most of the programming languages −

    If Conditional

    Fortran provides the following types of loop constructs to handle looping requirements. Click the following links to check their detail.

    Sr.NoLoop Type & Description
    1do loopThis construct enables a statement, or a series of statements, to be carried out iteratively, while a given condition is true.
    2do while loopRepeats a statement or group of statements while a given condition is true. It tests the condition before executing the loop body.
    3nested loopsYou can use one or more loop construct inside any other loop construct.

    Loop Control Statements

    Loop control statements change execution from its normal sequence. When execution leaves a scope, all automatic objects that were created in that scope are destroyed.

    Fortran supports the following control statements. Click the following links to check their detail.

    Sr.NoControl Statement & Description
    1exitIf the exit statement is executed, the loop is exited, and the execution of the program continues at the first executable statement after the end do statement.
    2cycleIf a cycle statement is executed, the program continues at the start of the next iteration.
    3stopIf you wish execution of your program to stop, you can insert a stop statement
  • JDK vs JRE vs JVM

    All three JDK, JRE and JVM are interdependent. JDK is Java Development Kit primarily meant for Developers to develop Java based applications. JRE is Java Runtime Environment where Java program runs. JDK carries JRE as an integral part of it. JRE can be installed seperately as well on systems where no developement is to be done and we only need to run the Java based application or a java program is to be executed. The JVM is a specification, and can have different implementations, as long as they adhere to the specs. The specs can be found in the below link − https://docs.oracle.com. JRE is an implementation of the JVM.

    JDK

    JDK is an abbreviation for Java Development Kit which includes all the tools, executables, and binaries required to compile, debug, and execute a Java Program.JDK is platform dependent i.e. there are separate installers for Windows, Mac, and Unix systems. JDK includes both JVM and JRE and is entirely responsible for code execution. It is the version of JDK that represents a version of Java.

    JRE

    JRE is a Java Runtime Environment which is the implementation of JVM i.e. the specifications that are defined in JVM are implemented and create a corresponding environment for the execution of code. JRE comprises mainly Java binaries and other classes to execute the program like JVM which physically exists. Along with Java binaries JRE also consists of various technologies of deployment, user interfaces to interact with code executed, some base libraries for different functionalities, and language and util-based libraries.

    JVM

    JVM is the abbreviation for Java Virtual Machine which is a specification that provides a runtime environment in which Java byte code can be executed i.e. it is something that is abstract and its implementation is independent of choosing the algorithm and has been provided by Sun and other companies. It is JVM which is responsible for converting Byte code to machine-specific code. It can also run those programs which are written in other languages and compiled to Java bytecode. The JVM performs the mentioned tasks: Loads code, Verifies code, Executes code, and Provides runtime environment.

    Difference between JDK, JRE, and JVM

    Following are the important differences between JDK, JRE, and JVM −

    Sr. No.KeyJDKJREJVM
    1DefinitionJDK (Java Development Kit) is a software development kit to develop applications in Java. In addition to JRE, JDK also contains number of development tools (compilers, JavaDoc, Java Debugger etc.).JRE (Java Runtime Environment) is the implementation of JVM and is defined as a software package that provides Java class libraries, along with Java Virtual Machine (JVM), and other components to run applications written in Java programming.JVM (Java Virtual Machine) is an abstract machine that is platform-dependent and has three notions as a specification, a document that describes requirement of JVM implementation, implementation, a computer program that meets JVM requirements, and instance, an implementation that executes Java byte code provides a runtime environment for executing Java byte code.
    2Prime functionalityJDK is primarily used for code execution and has prime functionality of development.On other hand JRE is majorly responsible for creating environment for code execution.JVM on other hand specifies all the implementations and responsible to provide these implementations to JRE.
    3Platform IndependenceJDK is platform dependent i.e for different platforms different JDK required.Like of JDK JRE is also platform dependent.JVM is platform independent.
    4ToolsAs JDK is responsible for prime development so it contains tools for developing, debugging and monitoring java application.On other hand JRE does not contain tools such as compiler or debugger etc. Rather it contains class libraries and other supporting files that JVM requires to run the program.JVM does not include software development tools.
    5ImplementationJDK = Java Runtime Environment (JRE) + Development toolsJRE = Java Virtual Machine (JVM) + Libraries to run the applicationJVM = Only Runtime environment for executing the Java byte code.
  • Decisions

    Decision making structures require that the programmer specify one or more conditions to be evaluated or tested by the program, along with a statement or statements to be executed, if the condition is determined to be true, and optionally, other statements to be executed if the condition is determined to be false.

    Following is the general form of a typical decision making structure found in most of the programming languages −

    Decision Making

    Fortran provides the following types of decision making constructs.

    Sr.NoStatement & Description
    1If… then constructAn if… then… end if statement consists of a logical expression followed by one or more statements.
    2If… then…else constructAn if… then statement can be followed by an optional else statement, which executes when the logical expression is false.
    3if…else if…else StatementAn if statement construct can have one or more optional else-if constructs. When the if condition fails, the immediately followed else-if is executed. When the else-if also fails, its successor else-if statement (if any) is executed, and so on.
    4nested if constructYou can use one if or else if statement inside another if or else if statement(s).
    5select case constructselect case statement allows a variable to be tested for equality against a list of values.
    6nested select case constructYou can use one select case statement inside another select case statement(s).
  • Java Virtual Machine(JVM)

    The JVM is a specification, and can have different implementations, as long as they adhere to the specs. The specs can be found in the below link − https://docs.oracle.com

    Oracle has its own JVM implementation (called the HotSpot JVM), the IBM has its own (the J9 JVM, for example).

    The operations defined inside the spec are given below (source − Oracle JVM Specs, see the above link) −

    • The ‘class’ file format
    • Data types
    • Primitive types and values
    • Reference types and values
    • Run-time data areas
    • Frames
    • Representation of objects
    • Floating-point arithmetic
    • Special methods
    • Exceptions
    • Instruction set summary
    • Class libraries
    • Public design, private implementation

    The JVM is a virtual machine, an abstract computer that has its own ISA, own memory, stack, heap, etc. It runs on the host OS and places its demands for resources to it.

    Architecture

    The architecture of the HotSpot JVM 3 is shown below −

    Architecture

    The execution engine comprises of the garbage collector and the JIT compiler. The JVM comes in two flavors − client and server. Both of these share the same runtime code but differ in what JIT is used. We shall learn more on this later. The user can control what flavor to use by specifying the JVM flags -client or -server. The server JVM has been designed for long-running Java applications on servers.

    The JVM comes in 32b and 64b versions. The user can specify what version to use by using -d32 or -d64 in the VM arguments. The 32b version could only address up to 4G of memory. With critical applications maintaining large datasets in memory, the 64b version meets that need.

    Class Loader

    The JVM manages the process of loading, linking and initializing classes and interfaces in a dynamic manner. During the loading process, the JVM finds the binary representation of a class and creates it.

    During the linking process, the loaded classes are combined into the run-time state of the JVM so that they can be executed during the initialization phase. The JVM basically uses the symbol table stored in the run-time constant pool for the linking process. Initialization consists of actually executing the linked classes.

    Types of Loaders

    The BootStrap class loader is on the top of the class loader hierarchy. It loads the standard JDK classes in the JRE’s lib directory.

    The Extension class loader is in the middle of the class loader hierarchy and is the immediate child of the bootstrap class loader and loads the classes in the JRE’s lib\ext directory.

    The Application class loader is at the bottom of the class loader hierarchy and is the immediate child of the application class loader. It loads the jars and classes specified by the CLASSPATH ENV variable.

    Linking

    The linking process consists of the following three steps −

    Verification − This is done by the Bytecode verifier to ensure that the generated .class files (the Bytecode) are valid. If not, an error is thrown and the linking process comes to a halt.

    Preparation − Memory is allocated to all static variables of a class and they are initialized with the default values.

    Resolution − All symbolic memory references are replaced with the original references. To accomplish this, the symbol table in the run-time constant memory of the method area of the class is used.

    Initialization

    This is the final phase of the class-loading process. Static variables are assigned original values and static blocks are executed.

    Runtime Data Areas

    The JVM spec defines certain run-time data areas that are needed during the execution of the program. Some of them are created while the JVM starts up. Others are local to threads and are created only when a thread is created (and destroyed when the thread is destroyed). These are listed below −

    PC (Program Counter) Register

    It is local to each thread and contains the address of the JVM instruction that the thread is currently executing.

    Stack

    It is local to each thread and stores parameters, local variables and return addresses during method calls. A StackOverflow error can occur if a thread demands more stack space than is permitted. If the stack is dynamically expandable, it can still throw OutOfMemoryError.

    Heap

    It is shared among all the threads and contains objects, classes’ metadata, arrays, etc., that are created during run-time. It is created when the JVM starts and is destroyed when the JVM shuts down. You can control the amount of heap your JVM demands from the OS using certain flags (more on this later). Care has to be taken not to demand too less or too much of the memory, as it has important performance implications. Further, the GC manages this space and continually removes dead objects to free up the space.

    Method Area

    This run-time area is common to all threads and is created when the JVM starts up. It stores per-class structures such as the constant pool (more on this later), the code for constructors and methods, method data, etc. The JLS does not specify if this area needs to be garbage collected, and hence, implementations of the JVM may choose to ignore GC. Further, this may or may not expand as per the application’s needs. The JLS does not mandate anything with regard to this.

    Run-Time Constant Pool

    The JVM maintains a per-class/per-type data structure that acts as the symbol table (one of its many roles) while linking the loaded classes.

    Native Method Stacks

    When a thread invokes a native method, it enters a new world in which the structures and security restrictions of the Java virtual machine no longer hamper its freedom. A native method can likely access the runtime data areas of the virtual machine (it depends upon the native method interface), but can also do anything else it wants.

    Garbage Collection

    The JVM manages the entire lifecycle of objects in Java. Once an object is created, the developer need not worry about it anymore. In case the object becomes dead (that is, there is no reference to it anymore), it is ejected from the heap by the GC using one of the many algorithms – serial GC, CMS, G1, etc.

    During the GC process, objects are moved in memory. Hence, those objects are not usable while the process is going on. The entire application has to be stopped for the duration of the process. Such pauses are called ‘stop-the-world’ pauses and are a huge overhead. GC algorithms aim primarily to reduce this time.

    Thanks to the GC, memory leaks are very rare in Java, but they can happen. We will see in the later topics how to create a memory leak in Java.

    The JIT Compiler

    In this topic, we shall learn about JIT compiler, and the difference between compiled and interpreted languages.

    Compiled vs. Interpreted Languages

    Languages such as C, C++ and FORTRAN are compiled languages. Their code is delivered as binary code targeted at the underlying machine. This means that the high-level code is compiled into binary code at once by a static compiler written specifically for the underlying architecture. The binary that is produced will not run on any other architecture.

    On the other hand, interpreted languages like Python and Perl can run on any machine, as long as they have a valid interpreter. It goes over line-by-line over the high-level code, converting that into binary code.

    Interpreted code is typically slower than compiled code. For example, consider a loop. An interpreted will convert the corresponding code for each iteration of the loop. On the other hand, a compiled code will make the translation only one. Further, since interpreters see only one line at a time, they are unable to perform any significant code such as, changing the order of execution of statements like compilers.

    We shall look into an example of such optimization below −

    Adding two numbers stored in memory. Since accessing memory can consume multiple CPU cycles, a good compiler will issue instructions to fetch the data from memory and execute the addition only when the data is available. It will not wait and in the meantime, execute other instructions. On the other hand, no such optimization would be possible during interpretation since the interpreter is not aware of the entire code at any given time.

    But then, interpreted languages can run on any machine that has a valid interpreter of that language.

    Is Java Compiled or Interpreted?

    Java tried to find a middle ground. Since the JVM sits in between the javac compiler and the underlying hardware, the javac (or any other compiler) compiler compiles Java code in the Bytecode, which is understood by a platform specific JVM. The JVM then compiles the Bytecode in binary using JIT (Just-in-time) compilation, as the code executes.

    HotSpots

    In a typical program, there’s only a small section of code that is executed frequently, and often, it is this code that affects the performance of the whole application significantly. Such sections of code are called HotSpots.

    If some section of code is executed only once, then compiling it would be a waste of effort, and it would be faster to interpret the Bytecode instead. But if the section is a hot section and is executed multiple times, the JVM would compile it instead. For example, if a method is called multiple times, the extra cycles that it would take to compile the code would be offset by the faster binary that is generated.

    Further, the more the JVM runs a particular method or a loop, the more information it gathers to make sundry optimizations so that a faster binary is generated.

    Let us consider the following code −

    for(int i =0;I<=100; i++){System.out.println(obj1.equals(obj2));//two objects}

    If this code is interpreted, the interpreter would deduce for each iteration that classes of obj1. This is because each class in Java has an .equals() method, that is extended from the Object class and can be overridden. So even if obj1 is a string for each iteration, the deduction will still be done.

    On the other hand, what would actually happen is that the JVM would notice that for each iteration, obj1 is of class String and hence, it would generate code corresponding to the .equals() method of the String class directly. Thus, no lookups will be required, and the compiled code would execute faster.

    This kind of behavior is only possible when the JVM knows how the code behaves. Thus, it waits before compiling certain sections of the code.

    Below is another example −

    int sum =7;for(int i =0; i <=100; i++){
       sum += i;}

    An interpreter, for each loop, fetches the value of ‘sum’ from the memory, adds ‘I’ to it, and stores it back into memory. Memory access is an expensive operation and typically takes multiple CPU cycles. Since this code runs multiple times, it is a HotSpot. The JIT will compile this code and make the following optimization.

    A local copy of ‘sum’ would be stored in a register, specific to a particular thread. All the operations would be done to the value in the register and when the loop completes, the value would be written back to the memory.

    What if other threads are accessing the variable as well? Since updates are being done to a local copy of the variable by some other thread, they would see a stale value. Thread synchronization is needed in such cases. A very basic sync primitive would be to declare ‘sum’ as volatile. Now, before accessing a variable, a thread would flush its local registers and fetch the value from the memory. After accessing it, the value is immediately written to the memory.

    Below are some general optimizations that are done by the JIT compilers −

    • Method inlining
    • Dead code elimination
    • Heuristics for optimizing call sites
    • Constant folding

    Compilation Levels

    JVM supports five compilation levels −

    • Interpreter
    • C1 with full optimization (no profiling)
    • C1 with invocation and back-edge counters (light profiling)
    • C1 with full profiling
    • C2 (uses profiling data from the previous steps)

    Use -Xint if you want to disable all JIT compilers and use only the interpreter.

    Client vs. Server JIT

    Use -client and -server to activate the respective modes.

    The client compiler (C1) starts compiling code sooner than the server compiler (C2). So, by the time C2 has started compilation, C1 would have already compiled sections of code.

    But while it waits, C2 profiles the code to know about it more than the C1 does. Hence, the time it waits if offset by the optimizations can be used to generate a much faster binary. From the perspective of a user, the trade-off is between the startup time of the program and the time taken for the program to run. If startup time is the premium, then C1 should be used. If the application is expected to run for a long time (typical of applications deployed on servers), it is better to use C2 as it generates much faster code which greatly offsets any extra startup time.

    For programs such as IDEs (NetBeans, Eclipse) and other GUI programs, the startup time is critical. NetBeans might take a minute or longer to start. Hundreds of classes are compiled when programs such as NetBeans are started. In such cases, C1 compiler is the best choice.

    Note that there are two versions of C1 − 32b and 64b. C2 comes only in 64b.

    Tiered Compilation

    In older versions on Java, the user could have selected one of the following options −

    • Interpreter (-Xint)
    • C1 (-client)
    • C2 (-server)

    It came in Java 7. It uses the C1 compiler to startup, and as the code gets hotter, switches to the C2. It can be activated with the following JVM options: -XX:+TieredCompilation. The default value is set to false in Java 7, and to true in Java 8.

    Of the five tiers of compilation, tiered compilation uses 1 -> 4 -> 5.

    32b vs. 64b

    On a 32b machine, only the 32b version of the JVM can be installed. On a 64b machine, the user has a choice between the 32b and the 64b version. But there are certain nuances to this that can affect how our Java applications perform.

    If the Java application uses less than 4G of memory, we should use the 32b JVM even on 64b machines. This is because memory references in this case would only be 32b and manipulating them would be less expensive than manipulating 64b addresses. In this case, the 64b JVM would perform worse even if we are using OOPS (ordinary object pointers). Using OOPS, the JVM can use 32b addresses in the 64b JVM. However, manipulating them would be slower than the real 32b references since the underlying native references would still be 64b.

    If our application is going to consume more than 4G memory, we will have to use the 64b version as the 32b references can address no more than 4G of memory. We can have both the versions installed on the same machine and can switch between them using the PATH variable.

    JIT Optimisations

    Here, we shall learn about JIT Optimisations.

    Method Inlining

    In this optimization technique, the compiler decides to replace your function calls with the function body. Below is an example for the same −

    int sum3;staticintadd(int a,int b){return a + b;}publicstaticvoidmain(String…args){
       sum3 =add(5,7)+add(4,2);}//after method inliningpublicstaticvoidmain(String…args){
       sum3 =5+7+4+2;}

    Using this technique, the compiler saves the machine from the overhead of making any function calls (it requires pushing and popping parameters to the stack). Thus, the generated code runs faster.

    Method inlining can only be done for non-virtual functions (functions that are not overridden). Consider what would happen if the ‘add’ method was over-ridden in a sub class and the type of the object containing the method is not known until runtime. In this case, the compiler would not know what method to inline. But if the method was marked as ‘final’, then the compiler would easily know that it can be inline because it cannot be over-ridden by any sub-class. Note that it is not at all guaranteed that a final method would be always in-lined.

    Unreachable and Dead Code Elimination

    Unreachable code is code that cannot be reached at by any possible execution flows. We shall consider the following example −

    voidfoo(){if(a)return;elsereturn;foobar(a,b);//unreachable code, compile time error}

    Dead code is also unreachable code, but the compiler does spit an error out in this case. Instead, we just get a warning. Each block of code such as constructors, functions, try, catch, if, while, etc., have their own rules for unreachable code defined in the JLS (Java Language Specification).

    Constant Folding

    To understand the constant folding concept, see the below example.

    finalint num =5;int b = num *6;//compile-time constant, num never changes//compiler would assign b a value of 30.

    Garbage Collection

    The lifecycle of a Java object is managed by the JVM. Once an object is created by the programmer, we need not worry about the rest of its lifecycle. The JVM will automatically find those objects that are not in use anymore and reclaim their memory from the heap.

    Garbage collection is a major operation that JVM does and tuning it for our needs can give a massive performance boosts to our application. There are a variety of garbage collection algorithms that are provided by modern JVMs. We need to be aware of our application’s needs to decide on which algorithm to use.

    You cannot deallocate an object programmatically in Java, like you can do in non-GC languages like C and C++. Therefore, you cannot have dangling references in Java. However, you may have null references (references that refer to an area of memory where the JVM won’t ever store objects). Whenever a null reference is used, the JVM throws a NullPointerException.

    Note that while it is rare to find memory leaks in Java programs thanks to the GC, they do happen. We will create a memory leak at the end of this topic.

    The following GCs are used in modern JVMs

    • Serial collector
    • Throughput collector
    • CMS collector
    • G1 collector

    Each of the above algorithms does the same task – finding objects that are no longer in use and reclaiming the memory that they occupy in the heap. One of the naïve approaches to this would be to count the number of references that each object has and free it up as soon as the number of references turn 0 (this is also known as reference counting). Why is this naïve? Consider a circular linked list. Each of its nodes will have a reference to it, but the entire object is not being referenced from anywhere, and should be freed, ideally.

    The JVM not only frees the memory, but also coalesces small memory chucks into bigger ones it. This is done to prevent memory fragmentation.

    On a simple note, a typical GC algorithm does the following activities −

    • Finding unused objects
    • Freeing the memory that they occupy in the heap
    • Coalescing the fragments

    The GC has to stop application threads while it is running. This is because it moves the objects around when it runs, and therefore, those objects cannot be used. Such stops are called ‘stop-the-world pauses and minimizing the frequency and duration of these pauses is what we aim while tuning our GC.

    Memory Coalescing

    A simple demonstration of memory coalescing is shown below

    Memory Coalescing

    The shaded portion are objects that need to be freed. Even after when all the space is reclaimed, we can only allocate an object of maximum size = 75Kb. This is even after we have 200Kb of free space as shown below

    Shaded Portion

    Generational GCs

    Most JVMs divide the heap into three generations − the young generation (YG), the old generation (OG) and permanent generation (also called tenured generation). What are the reasons behind such thinking?

    Empirical studies have shown that most of the objects that are created have very short lifespan −

    Empirical studies

    Source

    As you can see that as more and more objects are allocated with time, the number of bytes surviving becomes less (in general). Java objects have high mortality rate.

    We shall look into a simple example. The String class in Java is immutable. This means that every time you need to change the contents of a String object, you have to create a new object altogether. Let us suppose you make changes to the string 1000 times in a loop as shown in the below code −

    String str ="G11 GC";for(int i =0; i <1000; i++){
       str = str +String.valueOf(i);}

    In each loop, we create a new string object, and the string created during the previous iteration becomes useless (that is, it is not referenced by any reference). T lifetime of that object was just one iteration – they’ll be collected by the GC in no time. Such short-lived objects are kept in the young generation area of the heap. The process of collecting objects from the young generation is called minor garbage collection, and it always causes a ‘stopthe-world’ pause.

    As the young generation gets filled up, the GC does a minor garbage collection. Dead objects are discarded, and live objects are moved to the old generation. The application threads stop during this process.

    Here, we can see the advantages that such a generation design offers. The young generation is only a small part of the heap and gets filled up quickly. But processing it takes a lot lesser time than the time taken to process the entire heap. So, the ‘stop-theworld’ pauses in this case are much shorter, although more frequent. We should always aim for shorter pauses over longer ones, even though they might be more frequent. We shall discuss this in detail in later sections of this tutorial.

    The young generation is divided into two spaces − eden and survivor space. Objects that have survived during the collection of eden are moved to survivor space, and those who survive the survivor space are moved to the old generation. The young generation is compacted while it is collected.

    As objects are moved to the old generation, it fills up eventually, and has to be collected and compacted. Different algorithms take different approaches to this. Some of them stop the application threads (which leads to a long ‘stop-the-world’ pause since the old generation is quite big in comparison to the young generation), while some of them do it concurrently while the application threads keep running. This process is called full GC. Two such collectors are CMS and G1.

    Let us now analyze these algorithms in detail.

    Serial GC

    it is the default GC on client-class machines (single processor machines or 32b JVM, Windows). Typically, GCs are heavily multithreaded, but the serial GC is not. It has a single thread to process the heap, and it will stop the application threads whenever it is doing a minor GC or a major GC. We can command the JVM to use this GC by specifying the flag: -XX:+UseSerialGC. If we want it to use some different algorithm, specify the algorithm name. Note that the old generation is fully compacted during a major GC.

    Throughput GC

    This GC is default on 64b JVMs and multi-CPU machines. Unlike the serial GC, it uses multiple threads to process the young and the old generation. Because of this, the GC is also called the parallel collector. We can command our JVM to use this collector by using the flag: -XX:+UseParallelOldGC or -XX:+UseParallelGC (for JDK 8 onwards). The application threads are stopped while it does a major or a minor garbage collection. Like the serial collector, it fully compacts the young generation during a major GC.

    The throughput GC collects the YG and the OG. When the eden has filled up, the collector ejects live objects from it into either the OG or one of the survivor spaces (SS0 and SS1 in the below diagram). The dead objects are discarded to free up the space they occupied.

    Before GC of YG

    Before GC of YG

    After GC of YG

    After GC of YG

    During a full GC, the throughput collector empties the entire YG, SS0 and SS1. After the operation, the OG contains only live objects. We should note that both of the above collectors stop the application threads while processing the heap. This means long ‘stopthe- world’ pauses during a major GC. The next two algorithms aim to eliminate them, at the cost of more hardware resources −

    CMS Collector

    It stands for ‘concurrent mark-sweep’. Its function is that it uses some background threads to scan through the old generation periodically and gets rid of dead objects. But during a minor GC, the application threads are stopped. However, the pauses are quite small. This makes the CMS a low-pause collector.

    This collector needs additional CPU time to scan through the heap while running the application threads. Further, the background threads just collect the heap and do not perform any compaction. They may lead to the heap becoming fragmented. As this keeps going on, after a certain point of time, the CMS will stop all the application threads and compact the heap using a single thread. Use the following JVM arguments to tell the JVM to use the CMS collector −

    “XX:+UseConcMarkSweepGC -XX:+UseParNewGC” as JVM arguments to tell it to use the CMS collector.

    Before GC

    Before GC

    After GC

    After GC

    Note that the collection is being done concurrently.

    G1 GC

    This algorithm works by dividing the heap into a number of regions. Like the CMS collector, it stops the application threads while doing a minor GC and uses background threads to process the old generation while keeping the application threads going. Since it divided the old generation into regions, it keeps compacting them while moving objects from one region to another. Hence, fragmentation is minimum. You can use the flag: XX:+UseG1GC to tell your JVM to use this algorithm. Like CMS, it also needs more CPU time for processing the heap and running the application threads concurrently.

    This algorithm has been designed to process larger heaps (> 4G), which are divided into a number of different regions. Some of those regions comprise the young generation, and the rest comprise the old. The YG is cleared using traditionally – all the application threads are stopped and all the objects that are still alive to the old generation or the survivor space.

    Note that all GC algorithms divided the heap into YG and OG, and use a STWP to clear the YG up. This process is usually very fast.

    Tuning the GC

    In the last topic, we learnt about various Generational Gcs. In this topic, we shall discuss about how to tune the GC.

    Heap Size

    The heap size is an important factor in the performance of our Java applications. If it is too small, then it will get filled frequently and as a result, will have to be collected frequently by the GC. On the other hand, if we just increase the size of the heap, although it need to be collected less frequently, the length of the pauses would increase.

    Further, increasing the heap size has a severe penalty on the underlying OS. Using paging, the OS makes our application programs see much more memory than is actually available. The OS manages this by using some swap space on the disk, copying inactive portions of the programs into it. When those portions are needed, the OS copies them back from the disk to the memory.

    Let us suppose that a machine has 8G of memory, and the JVM sees 16G of virtual memory, the JVM would not know that there is in fact only 8G available on the system. It will just request 16G from the OS, and once it gets that memory, it will continue using it. The OS will have to swap a lot of data in and out, and this is a huge performance penalty on the system.

    And then comes the pauses which would occur during the full GC of such virtual memory. Since the GC will act on the entire heap for collection and compaction, it will have to wait a lot for the virtual memory to be swapped out of the disk. In case of a concurrent collector, the background threads will have to wait a lot for data to be copied from the swap space to the memory.

    So here the question of how we should decide on the optimal heap size comes. The first rule is to never request the OS more memory than is actually present. This would totally prevent the problem for frequent swapping. If the machine has multiple JVMs installed and running, then the total memory request by all of them combined is less than the actual RAM present in the system.

    You can control the size of memory request by the JVM using two flags −

    • -XmsN − Controls the initial memory requested.
    • -XmxN − Controls the maximum memory that can be requested.

    The default values of both these flags depend upon the underlying OS. For example, for 64b JVMs running on the MacOS, -XmsN = 64M and -XmxN = minimum of 1G or 1/4th of the total physical memory.

    Note that the JVM can adjust between the two values automatically. For example, if it notices that too much GC is happening, it will keep increasing the memory size as long as it is under -XmxN and the desired performance goals are met.

    If you know exactly how much memory your application needs, then you can set -XmsN = -XmxN. In this case, the JVM does not need to figure out an “optimal” value of the heap, and hence, the GC process becomes a little more efficient.

    Generation Sizes

    You can decide on how much of the heap do you want to allocate to the YG, and how much of it you want to allocate to the OG. Both of these values affect the performance of our applications in the following way.

    If the size of the YG is very large, then it would be collected less frequently. This would result in lesser number of objects being promoted to the OG. On the other hand, if you increase OG’s size too much, then collecting and compacting it would take too much time and this would lead to long STW pauses. Thus, the user has to find a balance between these two values.

    Below are the flags that you can use to set these values −

    • -XX:NewRatio=N: Ratio of the YG to the OG (default value = 2)
    • -XX:NewSize=N: YG’s initial size
    • -XX:MaxNewSize=N: YG’s max size
    • -XmnN: Set NewSize and MaxNewSize to the same value using this flag

    The initial size of the YG is determined by the value of NewRatio by the given formula −

    (total heap size)/(newRatio +1)

    Since the initial value of newRatio is 2, the above formula gives the initial value of YG to be 1/3 of the total heap size. You can always override this value by explicitly specifying the size of the YG using the NewSize flag. This flag does not have any default value, and if it is not set explicitly, the size of the YG will keep getting calculated using the above formula.

    Permagen and Metaspace

    The permagen and the metaspace are heap areas where the JVM keeps classes’ metadata. The space is called the ‘permagen’ in Java 7, and in Java 8, it is called the ‘metaspace’. This information is used by the compiler and the runtime.

    You can control the permagen’s size using the following flags: -XX: PermSize=N and -XX:MaxPermSize=N. Metaspace’s size can be controlled using: -XX:Metaspace-Size=N and -XX:MaxMetaspaceSize=N.

    There are some differences how the permagen and the metaspace are managed when the flag values are not set. By default, both have a default initial size. But while the metaspace can occupy as much of the heap as is needed, the permagen can occupy no more than the default initial values. For example, the 64b JVM has 82M of heap space as maximum permagen size.

    Note that since the metaspace can occupy unlimited amounts of memory unless specified not to, there can be an out of memory error. A full GC takes place whenever these regions are getting resized. Hence, during startup, if there are a lot of classes that are getting loaded, the metaspace can keep resizing resulting in a full GC every time. Thus, it takes a lot of time for large applications to startup in case the initial metaspace size is too low. It is a good idea to increase the initial size as it reduces the startup time.

    Though the permagen and metaspace hold the class metadata, it is not permanent, and the space is reclaimed by the GC, as in case of objects. This is typically in case of server applications. Whenever you make a new deployment to the server, the old metadata has to be cleaned up as new class loaders will now need space. This space is freed by the GC.

    Memory Leak in Java

    We shall discuss about the memory leak concept in Java here.

    The following code creates a memory leak in Java −

    voidqueryDB(){try{Connection conn =ConnectionFactory.getConnection();PreparedStatement ps = conn.preparedStatement("query");// executes aSQLResultSet rs = ps.executeQuery();while(rs.hasNext()){//process the record}}catch(SQLException sqlEx){//print stack trace}}

    In the above code, when the method exits, we have not closed the connection object. Thus, the physical connection remains open before the GC is triggered and sees the connection object as unreachable. Now, it will call the final method on the connection object, however, it may not be implemented. Hence, the object will not be garbage collected in this cycle.

    The same thing will happen in the next until the remote server sees that the connection has been open for a long time and forcefully terminates it. Thus, an object with no reference remains in the memory for a long time which creates a leak.

  • Constants

    The constants refer to the fixed values that the program cannot alter during its execution. These fixed values are also called literals.

    Constants can be of any of the basic data types like an integer constant, a floating constant, a character constant, a complex constant, or a string literal. There are only two logical constants : .true. and .false.

    The constants are treated just like regular variables, except that their values cannot be modified after their definition.

    Named Constants and Literals

    There are two types of constants −

    • Literal constants
    • Named constants

    A literal constant have a value, but no name.

    For example, following are the literal constants −

    TypeExample
    Integer constants0 1 -1 300 123456789
    Real constants0.0 1.0 -1.0 123.456 7.1E+10 -52.715E-30
    Complex constants(0.0, 0.0) (-123.456E+30, 987.654E-29)
    Logical constants.true. .false.
    Character constants“PQR” “a” “123’abc$%#@!”” a quote “” “‘PQR’ ‘a’ ‘123″abc$%#@!” an apostrophe ” ‘

    A named constant has a value as well as a name.

    Named constants should be declared at the beginning of a program or procedure, just like a variable type declaration, indicating its name and type. Named constants are declared with the parameter attribute. For example,

    real, parameter :: pi = 3.1415927
    

    Example

    The following program calculates the displacement due to vertical motion under gravity.

    program gravitationalDisp
    
    ! this program calculates vertical motion under gravity 
    implicit none  
    
       ! gravitational acceleration
       real, parameter :: g = 9.81   
       
       ! variable declaration
       real :: s ! displacement   
       real :: t ! time  
       real :: u ! initial speed  
       
       ! assigning values 
       t = 5.0   
       u = 50  
       
       ! displacement   
       s = u * t - g * (t**2) / 2  
       
       ! output 
       print *, "Time = ", t
       print *, 'Displacement = ',s  
       
    end program gravitationalDisp

    When the above code is compiled and executed, it produces the following result −

    Time = 5.00000000    
    Displacement = 127.374992    
    
  • Variables

    A variable is nothing but a name given to a storage area that our programs can manipulate. Each variable should have a specific type, which determines the size and layout of the variable’s memory; the range of values that can be stored within that memory; and the set of operations that can be applied to the variable.

    The name of a variable can be composed of letters, digits, and the underscore character. A name in Fortran must follow the following rules −

    • It cannot be longer than 31 characters.
    • It must be composed of alphanumeric characters (all the letters of the alphabet, and the digits 0 to 9) and underscores (_).
    • First character of a name must be a letter.
    • Names are case-insensitive.

    Based on the basic types explained in previous chapter, following are the variable types −

    Sr.NoType & Description
    1IntegerIt can hold only integer values.
    2RealIt stores the floating point numbers.
    3ComplexIt is used for storing complex numbers.
    4LogicalIt stores logical Boolean values.
    5CharacterIt stores characters or strings.

    Variable Declaration

    Variables are declared at the beginning of a program (or subprogram) in a type declaration statement.

    Syntax for variable declaration is as follows −

    type-specifier :: variable_name
    

    For example

    integer :: total  	
    real :: average 
    complex :: cx  
    logical :: done 
    character(len = 80) :: message ! a string of 80 characters

    Later you can assign values to these variables, like,

    total = 20000  
    average = 1666.67   
    done = .true.   
    message = “A big Hello from Tutorials Point” 
    cx = (3.0, 5.0) ! cx = 3.0 + 5.0i
    

    You can also use the intrinsic function cmplx, to assign values to a complex variable −

    cx = cmplx (1.0/2.0, -7.0) ! cx = 0.5 – 7.0i 
    cx = cmplx (x, y) ! cx = x + yi
    

    Example

    The following example demonstrates variable declaration, assignment and display on screen −

    Live Demo

    program variableTesting
    implicit none
    
       ! declaring variables
       integer :: total      
       real :: average 
       complex :: cx  
       logical :: done 
       character(len=80) :: message ! a string of 80 characters
       
       !assigning values
       total = 20000  
       average = 1666.67   
       done = .true.   
       message = "A big Hello from Tutorials Point" 
       cx = (3.0, 5.0) ! cx = 3.0 + 5.0i
    
       Print *, total
       Print *, average
       Print *, cx
       Print *, done
       Print *, message
       
    end program variableTesting

    When the above code is compiled and executed, it produces the following result −

    20000
    1666.67004    
    (3.00000000, 5.00000000 )
    T
    A big Hello from Tutorials Point         
    
  • Java vs C++

    Java is a general-purpose, high-level programming language. Java is used for web development, Machine Learning, and other cutting-edge software development. Java programming language was originally developed by Sun Microsystems which was initiated by James Gosling and released in 1995 as core component of Sun Microsystems’ Java platform (Java 1.0 [J2SE])

    C++ is a middle-level, case-sensitive, object-oriented programming language. Bjarne Stroustrup created C++ at Bell Labs. C++ is a platform-independent programming language that works on Windows, Mac OS, and Linux. C++ is near to hardware, allowing low-level programming. This provides a developer control over memory, improved performance, and dependable software.

    Read through this article to get an overview of C++ and Java and how these two programming languages are different from each other.

    What is Java?

    The latest release of the Java Standard Edition is Java SE 21. With the advancement of Java and its widespread popularity, multiple configurations were built to suit various types of platforms. For example: J2EE for Enterprise Applications, J2ME for Mobile Applications.

    The new J2 versions were renamed as Java SE, Java EE, and Java ME respectively. Java is guaranteed to be Write Once, Run Anywhere.

    Features of Java

    Java is −

    • Object Oriented − In Java, everything is an Object. Java can be easily extended since it is based on the Object model.
    • Platform Independent − Unlike many other programming languages including C and C++, when Java is compiled, it is not compiled into platform specific machine, rather into platform independent byte code. This byte code is distributed over the web and interpreted by the Java Virtual Machine (JVM) on whichever platform it is being run on.
    • Simple − Java is designed to be easy to learn. If you understand the basic concept of OOP Java, it would be easy to master.
    • Secure − With Java’s secure feature it enables to develop virus-free, tamper-free systems. Authentication techniques are based on public-key encryption.
    • Architecture-neutral − Java compiler generates an architecture-neutral object file format, which makes the compiled code executable on many processors, with the presence of Java runtime system.
    • Portable − Being architecture-neutral and having no implementation dependent aspects of the specification makes Java portable. Compiler in Java is written in ANSI C with a clean portability boundary, which is a POSIX subset.
    • Robust − Java makes an effort to eliminate error prone situations by emphasizing mainly on compile time error checking and runtime checking.
    • Multithreaded − With Java’s multithreaded feature it is possible to write programs that can perform many tasks simultaneously. This design feature allows the developers to construct interactive applications that can run smoothly.
    • Interpreted − Java byte code is translated on the fly to native machine instructions and is not stored anywhere. The development process is more rapid and analytical since the linking is an incremental and light-weight process.
    • High Performance − With the use of Just-In-Time compilers, Java enables high performance.
    • Distributed − Java is designed for the distributed environment of the internet.
    • Dynamic − Java is considered to be more dynamic than C or C++ since it is designed to adapt to an evolving environment. Java programs can carry extensive amount of run-time information that can be used to verify and resolve accesses to objects on run-time.

    Java Example

    Take a look at the following simple Java program −

    packagecom.tutorialspoint;importjava.util.Scanner;publicclassJavaTester{publicstaticvoidmain(String args[]){String a, b;Scanner scanner =newScanner(System.in);System.out.println("Enter The value for variable a");
    
      a = scanner.nextLine();System.out.println("Enter The value for variable b");
      b = scanner.nextLine();System.out.println("The value you have entered for a is "+ a);System.out.println("The value you have entered for b is "+ b);
      scanner.close();}}</code></pre>

    In our example, we have taken two variables "a" and "b" and assigning some value to those variables. Note that in Java, we need to declare datatype for variables explicitly, as Java is strictly typed language. As Java is an object oriented language, we uses objects to perform any action. In the example, we've used Scanner class object to read user input from console which is represented by System.in object. System.out object method println() is used to print the values received.

    Output

    On execution, this Java code will produce the following output −

    Enter The value for variable a
    10
    Enter The value for variable b
    20
    The value you have entered for a is 10
    The value you have entered for b is 20
    

    What is C++?

    C++ is a statically typed, compiled, multi-paradigm, general-purpose programming language with a steep learning curve. Video games, desktop apps, and embedded systems use it extensively. C++ is so compatible with C that it can build practically all C source code without any changes. Object-oriented programming makes C++ a better-structured and safer language than C.

    Features of C++

    Let's see some features of C++ and the reason of its popularity.

    • Middle-level language − It's a middle-level language since it can be used for both systems development and large-scale consumer applications like Media Players, Photoshop, Game Engines, etc.
    • Execution Speed − C++ code runs quickly. Because it's compiled and uses procedures extensively. Garbage collection, dynamic typing, and other modern features impede program execution.
    • Object-oriented language − Object-oriented programming is flexible and manageable. Large apps are possible. Growing code makes procedural code harder to handle. C++'s key advantage over C.
    • Extensive Library Support − C++ has a vast library. Third-party libraries are supported for fast development.

    C++ Example

    Let's understand the syntax of C++ through an example written below.

    #includeusingnamespace std;intmain(){int a, b;
       cout <<"Enter The value for variable a \n";
       cin >> a;
       cout <<"Enter The value for variable b";
       cin >> b;
       cout <<"The value of a is "<< a <<"and"<< b;return0;}

    In our example, we are taking input for two variables "a" and "b" from the user through the keyboard and displaying the data on the console.

    Output

    On execution, it will produce the following output −

    Enter The value for variable a
    10
    Enter The value for variable b
    20
    The value of a is 10 and 20
    

    Difference Between Java and C++

    Both Java and C++ are among the most popular programming languages. Both of them have their advantages and disadvantages. In this tutorial, we shall take a closure look at their characteristic features which differentiate one from another.

    Sr.No.CriteriaJavaC++
    1Developed byJava was developed by James Gosling at Sun Microsystems. Initially it was designed for embedded systems, settop boxes, televisions etc. Later it become a preferred language for internet based application developmentC++ was developed by Bjarne Stroustrup at Bell Labs, as an extension to C language. It supports both high level as well as low level machine code access. C++ is mainly used to develop system softwares, compilers etc.
    2Influenced byIt was influenced by Ada 83, Pascal, C++, C#.It was influenced by Ada, ALGOL 68, C, ML, Simula, Smalltalk.
    3Dependency on ArchitectureThe Java bytecode works on any operating System. Bytecode is targeted for JVM. JVM or Java Virtual Machine then interpret the byte code and run the underlying machine specific code. Thus Java code needs not to be changed to run on different machines.It doesn't work on every operating system since libraries are different on different systems.
    4Platform independenceIt can run on any OS. Java code is platform independent. No platform specific code is required. Size of int, long remains same on all platforms.It is compiled differently on different platforms, can't be run on any OS.
    5PortablityIt is portable. Being platform independent, a java code can be transferred as it is on any machine without any plaform specific modification. A java code written in Windows machine can run in Unix machine in same fashion without any modification.It isn't portable.
    6Interpreted/CompiledIt is an interpreted language.It is a compiled language.
    7Memory managementMemory management is done automatically. Java provides Garbage Collector service which automatically deallocates memory once an object is not required.Memory management is to be done manually.
    8virtual KeywordIt doesn't have ‘virtual' keyword.It has the ‘virtual' keyword.
    9Multiple Inheritance supportIt supports single inheritance only. Multiple inheritance can be achieved using interfaces (partial only). A class can extend only a single class. Although interface can extend multiple inheritance. Multiple inheritance can lead to ambigous results. As virtual keyword is not supported in Java, multiple inhertance is not supported.It supports single and multiple Inheritance. Using virtual keyword, ambigous reference can be resolved.
    10operator overloading supportIt doesn't support operator overloading. Java supports only method overloading. Operator overloading is considered to add the complexity to base language so is not implemented to keep language simple.It supports operator overloading. In C++, we can overload both methods and operators.
    11pointersIt provides limited support to pointers. Pointers being a complex functionality, Java refrains from using them. It provides concept of reference to point to objects or precisely their addresses.It supports pointer operations. Developers can perform complex operations, can write optimized memory based code using pointers. But it is quite complex and requires strong programming skills to master them.
    12Low level machine code accessThey have high level functionalities. Java is platform independent language and the compiled code of java as byte code is for JVM which further converts code to low level code. So using java, developer cannot write low level machine code. This is the reason, that Java is mainly used for application development.They have low level functionalities. As C++ supports low level machine code code. It is mainly used to write system softwares, compilers etc.
    13Native libraries accessIt doesn't support direct native library call. Java is not designed to work with low level machine code and it is not supporting native call. But we can configure native call using third party libraries.It supports direct system library calls.
    14documentation commentIt supports documentation comment (/**.. */) for source code. Javadoc tool can read the documentation comments from source code and generate html based java documentation based on the comments.It doesn't support documentation comment for source code.
    15MultithreadingIt supports thread operations. Java has by default support for multithreading. It allows concurrent programming to improve efficiency and to reduce time takenIt doesn't support threads by design. It can be done by using third party threading libraries.
    16Console InputIt uses the 'System' class, i.e System.in for input. System.in class can be used to take input from user on console.It uses 'cin' for input operation. cin allows user to enter value in console.
    17Console OutputIt uses System.out for output. System.out.println() method prints the required value on system's console.It uses 'cout' for an output operation. cout prints the required value on system's console.
    19global supportIt doesn't support global scope. Java is a strict object oriented language and global scope is not available. Using packages, it supports across package scope though.It supports global scope as well as namespace scope.
    20struct/union supportIt doesn't support structures and unions.It supports structures and unions.
    21goto keywordIt doesn't have the 'goto' keyword. But same functionality is achivable using label. A break/continue statement can jump to a labelled statement location.It supports the 'goto' keyword. Using goto keyword, we can jump to any labelled location.
    22pass by value/referenceIt supports Pass by Value method only. Even object reference is technically passed to a method as value.It supports Pass by Value and pass by reference methods. In case of pass by reference, pointer or & notation is required.
    23Memory ManagementIt performs object management automatically using garbage collector. Developers are not required to do memory allocation for objects or deallocate them when objects are not in use. Garbage Collector service automatically detects and frees up the space. Due to GC service, memory leaks are very less possible in Java.It performs object management manually with the help of ‘new' and ‘delete'. Developers have to take measures to ensure memory is properly allocated/deallocated to prevent memory leaks.