Welcome to the Virtual Machine

Thomas Broussard
  • What is Java?

    This section performs an overview about the Java language, history and base concepts are quickly described

    History: Java and the JVM

    What was there before Java? We are in 1995, and the C and C++ languages dominate the world of programming at this date. Although these languages are very efficient in their own scopes, programmers are spending a lot of time in porting applications from one environment to another, because programs use directly the native libraries of each system, and this implies to change a part of a program when you want it to run on different environment...

    Note on the code portability

    C/C++ developers are aware of those platform-specific problem. Specific codes are generally separated from the rest of the logic. These developers must stay attentive, because some native APIs can be unintentionally inserted into the general code.

    Also, sometimes the general logic and the specific code do not dissociate properly, for example the following code (found here )

                                
    /*here is a tiny example which lists the files in the current directory*/
    #include <stdio.h>
    #include <sys/types.h>
    #include <dirent.h>
    
    int main(){
        struct dirent *dp;
        dir *dfd = opendir(".");
        if(dfd != null) {
            while((dp = readdir(dfd)) != null){
                printf("%s\n", dp->d_name); /*you can't do much better without a specific API*/
            }
            closedir(dfd);
        }
        return 0;
    }
                                
                            

    In this sample, you can't do much more than reading files name staying cross-platform. If you want to do more, you must call native environment APIs, which makes your code adherent to this platform

    This is pretty bad, because the cost of porting an application does not stop to the native calls area, this also affects the rest of the program, because native calls does not behave the same way. An other cost is the validation of each environment.

    An other thing which is environment specific is the binary produced by the compilation : even if you took great care about using cross-platform APIs, there you do not have the choice. Each system has its specific format for binary executable (.exe, .dll for Windows .elf, .so for Linux etc.). It adds to the validation an other cost, because these different type of files does not behave equally, and their generation can also bring errors during execution.

    From this observation, a company named Sun produced at this date (remember, we're in 1995) a totally new and revolutionary system: the Java Virtual Machine (JVM).

    Abstraction

    This JVM *is* itself an environment, but a special one: it is Virtual. That means that by itself, a JVM can do nothing:

    • The JVM must have a physical host, because the JVM is only a program that runs on an host
    • The JVM must have been designed for this host
    • The JVM only reads Java byte code

    Those 3 remarks allow to see a bit more clearly the goal of the JVM: The JVM abstracts the code written in Java from those bad native calls that cost developers so much time! In fact, the code is written in Java, this code is compiled to make a .class which is the kind of file the JVM can work with. This code is converted by the JVM that delegates native calls to its specific implementation and everything that will lead to an environment specific treatment (filesystem access, network etc.) is handled by the JVM, totally transparently for the programmer

    An OOP language

    You probably noticed the term .class is mentioned just above. Indeed, Java is an Object Oriented Programming language. This is not strong enough: Java is Massively Object Oriented! In Java, every little thing is an object

    It implies that every files produced during the compilation phase is a .class file

    Automatic Memory Management

    The main bug source in languages like C and C++, is that you manage the memory yourself. It may seem mandatory in certain case, but in most of the case, the lack of concentration of a developer can ruin the fine work of his colleagues.

    The JVM proposes an automatic memory management system which allows developers to be free of that concern! You simply use what you need to use and the system automatically send to garbage what you don't need anymore. In fact a good knowledge of what is done behind the scene is required, but this avoid to consume time in a lot of cases.

    This mechanism is called Garbage Collection. A garbage collector is an entity inside the jvm that handles useless objects. Its action is configurable, as it lays on interchangeable algorithms.

    Conclusion

    Java is more than a language, it is an environment, where several components are involved. Java allows developer to gain time when designing applications, and also when they deploy them across several environment.


  • Java programing, structure and syntax

    Be ready, this part will be rough but you cannot pretend to have skills in Java without reading it

    So... We said that in Java, everything was an object? This is true 99.9% of the time, so we'll start with learning what is a class structure

    The class, a Java object

    Java Objects representation is made through a "class" file. At the beginning, the class is a java file. The class name is the way this object will be called in the developer code. This name must be the name of the file containing this class definition. The extension of a non compiled class (the way human usually edit classes) is *.java

    There is an example below:

    package fr.tbr.demo;
    
    /**
     * @author Thomas Broussard
     *         Date: 29/09/13
     */
    public class MyDemoClass {
        /**
         * A private field that must be initialized during the instance construction phase
         */
        private String mainText;
    
        /**
         * private integer field, this is a primitive type
         */
        private int age;
    
        /**
         * A final field that never changes during the execution
         */
        private static final String AUTHOR = "Thomas Broussard";
    
        /**
         * Static method to get a data shared by all of the instances of MyDemoClass
         * @return the author of the class
         */
        public static String getAuthor() {
            return AUTHOR;
        }
    
        /**
         * Constructor of a MyDemoClass object
         * @param mainText
         */
        public MyDemoClass(String mainText) {
            this.mainText = mainText;
    		this.age=28;
        }
    
        /**
         * Performs a demo on the current instance of MyDemoClass
         */
        public void doTheDemo() {
               String result =  "This wonderful demo class has been written by "
                       + AUTHOR + " and this object has been initialized with :"
                       + this.mainText;
               System.out.println(result);    // access to the standard output
        }
    
        /**
         * A method that overrides the Object (super class of all classes);
         * @return a String containing the mainText field value
         */
        @Override
        public String toString() {
            return mainText;
        }
    }
    
    
    					
    
    					

    This is how we can define an object in Java, the following items are to be explained:

    • The first line : the package declaration

      The first line defines the package in which the class is located. A package is represented physically by a folder, and it is where the .java files will be reachable. A package is a necessary mean to organize the code, and generally avoid mistakes when the project grows bigger. Indeed, the package name can be used to

      It is advised to define a namespace using the package tree ; a namespace is a (normally) unique prefix, indicating that the code inside any sub tree of this namespace is yours

      This is necessary to avoid class naming collision (two classes having the same name). In this example, the namespace is fr.tbr

    • The "weird" comment: Javadoc

      In java, you have powerful allies. Like in all languages you have comment at your disposal to indicate a critical part of your program

      This is good, but in fact this is the true minimum. Java can help you better, thanks to the Javadoc system. The javadoc system is an improvement of the comment principle, allowing developer to generate a technical documentation directly from the code

      To indicate a Javadoc comment, you'll have to dispose a simple block comment "A la C" and add a second star, examples below:

      /** Javadoc */
      /* Block comment */
      // Line comment 

      The Javadoc is part of your Java program, it is standard and you'll have to provide javadoc on everything that is public This will help your teammates to understand and to reuse your code quickly. Indeed, the Javadoc will be compiled (if asked) in a browseable html format, an example is here: Apache commons Javadoc

      You may have noticed a strange @author indication, this is the way the javadoc system indicates the author of a program part. Several keywords exist, allowing to highlight what is generally important to in a program

    • What really matters: the Class definition

      Notice the class definition

      public class MyDemoClass {
      //...
      }

      There are three things to note:

      • public this is the Visibility modifier

        It is a classical feature of OOP languages, it allows the developer to select which method is reachable by another class code. The class which the name is the same as the compilation unit must be public (or package protected, although this is usually not what you want to do)

        This modifier system is applicable to any other entities composing the class

        Modifier name Effect
        public

        This modifier indicates that every class can access to the entity

        protected

        Only sub-classes (via inheritance) can have access to elements marked with this identifier

        private

        Only the current class can have access to private properties

        (none)

        When no modifier is specified, it means the property is only reachable by classes located in the same package

      • class indicates this is a class, there are several kinds of entities

        Several values are possible

        Kind of entity Description
        class

        It means the current compilation unit is a class, meaning it represents an object

        interface

        Interfaces are the way Java defines "meta-class", you can see it as a characteristic shared by several classes. A typical real-world example is to say that a dog can howl and so does a wolf, although a dog is not a wolf and vice-versa. An interface "Howler" can be defined so the behaviour of howling can be shared by several classes, even if these classes do not inherit from one to each other.

        This quick definition of interfaces will be completed in a dedicated part of this course

        enum

        Enums are specific objects. the word "enum" stands for "enumeration" and the goal of this kind of class is contained inside this word: they are to represent a constant collection of objects

        An enum is very useful when you want to structure your code, it is a recommended way to define property of an object when this object has to leave its Java Object shape (ie, when this object is required to be serialized)

      • MyDemoClass this is the name of the object that defines the class. The compilation unit (the name of the Java file) must be the same, here MyDemoClass.java
    Class fields

    In the previous example, there are two class fields : the first is of type String, the second is declared as an int what other kinds of Java built-in types could you see in a program?

    Two main kinds of types in Java

    Java has two kinds of types: the primitive and the object types... Remember? we said that every thing was an object in Java, this is wrong again.

    Primitive types

    The primitive types look like C native types, although they have a default value. You will find a description of these types hereafter:

    Primitive type Description Range
    Integer types
    byte

    a signed byte

    -128 to 127

    short

    This is a two-bytes signed integer, it defaults to 0 if not initialized

    -32,768 to 32,767

    int

    This is a signed integer, it defaults to 0 if not initialized

    -2,147,483,648 to 2,147,483,647 (inclusive)

    long

    The long is a signed integer with a wider range:

    the declaration of a long is a bit different, you should do it as described below

    						
    long primitiveLong = 1222222333335555l;
    						
    					

    -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807

    Floating types
    float

    The float is a signed floating point number

    1.40129846432481707e-45 to 3.40282346638528860e+38

    double

    The double is a type aiming at covering a very large range of values. However, its usage is discouraged since it is addressed on a 8 bytes format. If you use large tables of values, prefer float (if the range is ok for that)

    4.94065645841246544e-324d to 1.79769313486231570e+308d

    Other
    boolean

    the boolean in Java can have two values true or false, which are reserved keywords of the language

    true or false
    char

    2 bytes, unsigned, Unicode, char are used to represent characters, but are not directly compatible with integers or Strings

    0 to 65,535

    The Object type

    The Object type allows to reference an other object inside your main object, this is a normal object what can be built-in or "custom" (meaning your own object). Among the noticeable built-in types, there are:

    • String : this is the way to represent a characters string in Java
    • Integer : this is one of the numerous objects representing a raw type in the object style. If you want to read more of that, consider reading the Autoboxing paragraph, just below.
    • Other complex data structures : read more on the next level about lists, maps, XML manipulations etc. here >>
    Autoboxing

    The Autoboxing mechanism is integrated in Java. It allows to convert an object into a primitive type, as the code shows below:

    	
    /**
     * Shows how primitive types can be "boxed" (automatically cast) to Objects
     */
        final char character = 0;
        final byte veryShortInt = 0;
        final short shortInt = 0;
        final int normalInt = 0;
        final long longInt = 0l;
    
        final float floatingPoint = 0;
        final double bigFloatingPoint = 0;
    
        final boolean aBooleanExample = true;
    
        // Object style
    
        final Byte byteSample = veryShortInt;
        final Short shortSample = shortInt;
        final Integer intSample = normalInt;
        final Long longSample = longInt;
    
        final Float floatSample = floatingPoint;
        final Double doubleSample = bigFloatingPoint;
    
        final Boolean booleanSample = aBooleanExample;
    	
    
    Using the defined object

    How to use the defined object? We should introduce a new keyword : the well named new operator. The new operator allows to create a new instance of the defined class reference.

    In order to understand better the object concept in Java, you have to understand that one class is the "template" of an object, this is only a definition. When you use instances of that class, they all have their own fields values.

    Only things shared by all theses instances are the static fields. Static fields are common to all instances, allowing to share data between them.

    An example with an "Identity" object
    Identity String displayName String uid String email Map<String,String> attributes
    Definition Instances Identity Quentin Clément Thomas "new" Operator example: Identity Thomas = new Identity("Thomas");

    In the code, you'll have to do the instanciation like the following :

    Identity thomas = new Identity("Thomas Broussard", "01", "t.b@sample.com");
    Identity quentin = new Identity("Quentin", "02", "q.d@sample.com");
    Identity clement = new Identity("Clément", "03", "c.s@sample.com");
    
    Use the Java objects

    We saw just before how to create new Java objects, now how to use them ?

    To use an object, this object should already have a built-in behaviour to invoke in this object user's code. As an example, let's define an object representing a car:

    Car definition
    Car String model String brand boolean engineStarted Car(String model, String brand) void start() void stop() String toString()

    There is the code hereafter :

    		package fr.tbr.demo;
    
    /**a car representation*/
    public class Car{
    
        private String model;
        private String brand;
    
        private boolean engineStarted;
    
    
        public Car(String model, String brand) {
    		super();
    		this.model = model;
    		this.brand = brand;
        }
    
        public void start(){
    		this.engineStarted = true;
        }
    
        public void stop(){
    		this.engineStarted = false;
        }
    
        @Override
        public String toString() {
    		return "Car [model=" + model + ", brand=" + brand +
    			", engineStarted=" + engineStarted + "]";
        }
    
    }
    	

    Here the object has two behaviours, start() and stop(). Each action has an effect on the car state. In Java, the way of making a call to these behaviours is :

    	
    Car timeMachine = new Car("DeLorean-DMC12", "DMC");
    timeMachine.start();
    timeMachine.stop();
    	
    
    Objects concepts in Java
    • Inheritance

      The inheritance mechanism is defined via the extends keyword

      To follow the previous example, the way to define an inheritance between a motor-vehicle and a car (specialization) is defined by the code after

      Inheritance
      CarString modelString brandCar(String model, String brand)String toString()MotorVehicleString engineTypeboolean engineStartedvoid start()void stop()

      And the UML schema

      
      package fr.tbr.demo;
      
      /**a car representation*/
      public class Car extends MotorVehicle{
      
      
      
          private String model;
          private String brand;
      
      
      
      
          public Car(String model, String brand) {
      	super();
      	this.model = model;
      	this.brand = brand;
          }
      
      
      
          @Override
          public String toString() {
      	String returned = "Car [model=" + model +
      			", brand=" + brand + ", engineStarted=" + engineStarted + "]";
      	Car timeMachine = new Car("DeLorean-DMC12", "DMC");
      	timeMachine.start();
      	timeMachine.stop();
      	return returned;
      
          }
      }
      		

      Notice that you can use the properties of the parent object in the inherited object thanks to the super operator

    Common operators

    In Java there are a lot of operators, only a little part is daily used. This part presents these operators and how to use them in a java program