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

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

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

    
    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;
    
        }
    }
    		

    And the UML schema

    Inheritance

    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