Saturday, 11 January 2014

Containment and Inheritance


Containment & inheritance are ways of code re-usability. Containment is a 'has-a' relationship while Inheritance is a 'is-a' relationship. Containment means use of object of one class in another while inheritance means reusing the features of a class in its derived class.

Containment:
Containment relationship means the use of an object of a class as a member of another class. Containment is a 'has-a' relation. e.g. an employee 'has-a' joining date.
Example:
class Employee
{
  int emp_id;
  String emp_name;
  MyDate date;   //MyDate is a class having date, month and year

  Emp()
  {
    emp_id=0;
    emp_name="abc";
    date=new MyDate();
  }

  Emp(int id, String name, MyDate d)
  {
    emp_id=id;
    emp_name=name;
    date=d;
  }

public static void main(String args[])
{
  Emp e1=new Emp();
  Emp e2=new Emp(123,"java", new MyDate(23,5,2012));
//to execute this,one needs to write MyDate class
}
}

Inheritance:
Inheritance involves deriving a class from a parent or base class. Inheritance is a 'is-a' relation. e.g.a car 'is-a' vehicle. Inheritance can be used only if one class has ability to behave like other class
Example:
package test;

import date.Date;
public class Employee {
int emp_id,emp_phno,emp_sal;
Date dob;
String name,city;
public Employee(int id,int phno,int sal,String nm,String ct,Date d) {
emp_id = id;
emp_phno = phno;
emp_sal = sal;
name = nm;
city = ct;
dob = d;
}
public void getsal(int sal) {
emp_sal = sal;
}
public String toString() {
return "ID:"+emp_id+"\tName:"+name+"\tContact No:"+emp_phno+"\tCity:"+city+"\tDate of joining:"+dob;
}
public static void main(String[] args) {
Employee emp = new Employee(1, 223323, 30000, "Reshma", "Pune", new Date(1,2,2013));
emp.getsal(30000);
System.out.println(emp+"\tSalary:"+emp.emp_sal);
}
}
----
package test;
import date.Date;
public class Manager extends Employee{

int target, incentives,mgr_sal;
Employee e;
public Manager(int trgt, int inc) {
super(2, 5, 400, "Xyz", "Mnb", new Date(12,3,2012));
target = trgt;
incentives = inc;
mgr_sal = 0;
e = new Employee(2, 332244, 40000, "Shweta", "Mumbai", new Date(12,3,2000));
}
public void getsal(int sal) {
mgr_sal = sal+incentives; 
}
public String toString() {
return e+"\tSalary:"+mgr_sal;
}
public static void main(String[] args) {
Manager mgr = new Manager(100000, 20000);
mgr.getsal(50000);
System.out.println(mgr);
}
}

Garbage Collection

Garbage Collection: 
Garbage collection (GC) is the process that aims to free up occupied memory that is no longer referenced by any reachable Java object, and is an essential part of the Java virtual machine's (JVM's) dynamic memory management system. In a typical garbage collection cycle all objects that are still referenced, and thus reachable, are kept. The space occupied by previously referenced objects is freed and reclaimed to enable new object allocation.

Garbage collection and the Java platform memory model

When you specify the startup option -Xmx on the command line of your Java application (for instance: java -Xmx:2g MyApp) memory is assigned to a Java process. This memory is referred to as the Java heap (or just heap). This is the dedicated memory address space where all objects created by your Java program (or sometimes the JVM) will be allocated. As your Java program keeps running and allocating new objects, the Java heap (meaning that address space) will fill up.

Eventually, the Java heap will be full, which means that an allocating thread is unable to find a large-enough consecutive section of free memory for the object it wants to allocate. At that point, the JVM determines that a garbage collection needs to happen and it notifies the garbage collector. A garbage collection can also be triggered when a Java program calls System.gc(). Using System.gc() does not guarantee a garbage collection. Before any garbage collection can start, a GC mechanism will first determine whether it is safe to start it. It is safe to start a garbage collection when all of the application's active threads are at a safe point to allow for it, e.g. simply explained it would be bad to start garbage collecting in the middle of an ongoing object allocation, or in the middle of executing a sequence of optimized CPU instructions, as you might lose context and thereby mess up end results.

A garbage collector should never reclaim an actively referenced object; to do so would break the Java virtual machine specification. A garbage collector is also not required to immediately collect dead objects. Dead objects are eventually collected during subsequent garbage collection cycles. While there are many ways to implement garbage collection, these two assumptions are true for all varieties. The real challenge of garbage collection is to identify everything that is live (still referenced) and reclaim any unreferenced memory, but do so without impacting running applications any more than necessary. A garbage collector thus has two mandates:

  1. To quickly free unreferenced memory in order to satisfy an application's allocation rate so that it doesn't run out of memory.
  2. To reclaim memory while minimally impacting the performance (e.g., latency and throughput) of a running application.

Two kinds of garbage collection

Reference counting collectors

Reference counting collectors keep track of how many references are pointing to each Java object. Once the count for an object becomes zero, the memory can be immediately reclaimed. This immediate access to reclaimed memory is the major advantage of the reference-counting approach to garbage collection. There is very little overhead when it comes to holding on to un-referenced memory. Keeping all reference counts up to date can be quite costly, however.

The main difficulty with reference counting collectors is keeping the reference counts accurate. Another well-known challenge is the complexity associated with handling circular structures. If two objects reference each other and no live object refers to them, their memory will never be released. Both objects will forever remain with a non-zero count. Reclaiming memory associated with circular structures requires major analysis, which brings costly overhead to the algorithm, and hence to the application.

Tracing collectors

Tracing collectors are based on the assumption that all live objects can be found by iteratively tracing all references and subsequent references from an initial set of known to be live objects. The initial set of live objects (called root objects or just roots for short) are located by analyzing the registers, global fields, and stack frames at the moment when a garbage collection is triggered. After an initial live set has been identified, the tracing collector follows references from these objects and queues them up to be marked as live and subsequently have their references traced. Marking all found referenced objects live means that the known live set increases over time. This process continues until all referenced (and hence all live) objects are found and marked. Once the tracing collector has found all live objects, it will reclaim the remaining memory.

Tracing collectors differ from reference-counting collectors in that they can handle circular structures. The catch with most tracing collectors is the marking phase, which entails a wait before being able to reclaim non-referenced memory.

Tracing collectors are most commonly used for memory management in dynamic languages; they are by far the most common for the Java language and have been commercially proven in production environments for many years. 

Tracing collector algorithms

Copying and mark-and-sweep garbage collection are not new, but they're still the two most common algorithms that implement tracing garbage collection today.

Copying collectors

Traditional copying collectors use a from-space and a to-space -- that is, two separately defined address spaces of the heap. At the point of garbage collection, the live objects within the area defined as from-space are copied into the next available space within the area defined as to-space. When all the live objects within the from-space are moved out, the entire from-space can be reclaimed. When allocation begins again it starts from the first free location in the to-space.

In older implementations of this algorithm the from-space and to-space switch places, meaning that when the to-space is full, garbage collection is triggered again and the to-space becomes the from-space.


More modern implementations of the copying algorithm allow for arbitrary address spaces within the heap to be assigned as to-space and from-space. In these cases they do not necessarily have to switch location with each other; rather, each becomes another address space within the heap.

One advantage of copying collectors is that objects are allocated together tightly in the to-space, completely eliminating fragmentation. Fragmentation is a common issue that other garbage collection algorithms struggle with.
Downsides of copying collectors

Copying collectors are usually stop-the-world collectors, meaning that no application work can be executed for as long as the garbage collection is in cycle. In a stop-the-world implementation, the larger the area you need to copy, the higher the impact on your application performance will be. This is a disadvantage for applications that are sensitive to response time. With a copying collector you also need to consider the worst-case scenario, when everything is live in the from-space. You always have to leave enough headroom for live objects to be moved, which means the to-space must be large enough to host everything in the from-space. The copying algorithm is slightly memory inefficient due to this constraint.

Mark-and-sweep collectors

Most commercial JVMs deployed in enterprise production environments run mark-and-sweep (or marking) collectors, which do not have the performance impact that copying collectors do. Some of the most famous marking collectors are CMS, G1, GenPar, and DeterministicGC.
A mark-and-sweep collector traces references and marks each found object with a "live" bit. Usually a set bit corresponds to an address or in some cases a set of addresses on the heap. The live bit can, for instance, be stored as a bit in the object header, a bit vector, or a bit map.

After everything has been marked live, the sweep phase will kick in. If a collector has a sweep phase it basically includes some mechanism for traversing the heap again (not just the live set but the entire heap length) to locate all the non-marked chunks of consecutive memory address spaces. Unmarked memory is free and reclaimable. The collector then links together these unmarked chunks into organized free lists. There can be various free lists in a garbage collector -- usually organized by chunk sizes. Some JVMs (such as JRockit Real Time) implement collectors with heuristics that dynamically size-range lists based on application profiling data and object-size statistics.

When the sweep phase is complete allocation will begin again. New allocation areas are allocated from the free lists and memory chunks could be matched to object sizes, object size averages per thread ID, or the application-tuned TLAB sizes. Fitting free space more closely to the size of what your application is trying to allocate optimizes memory and could help reduce fragmentation.

Downsides of mark-and-sweep collectors

The mark phase is dependent on the amount of live data on your heap, while the sweep phase is dependent on the heap size. Since you have to wait until both the mark and sweep phases are complete to reclaim memory, this algorithm causes pause-time challenges for larger heaps and larger live data sets.

One way that you can help heavily memory-consuming applications is to use GC-tuning options that accommodate various application scenarios and needs. Tuning can, in many cases, help at least postpone either of these phases from becoming a risk to your application or service-level agreements (SLAs). (An SLA specifies that the application will meet certain application response times -- i.e., latency.) Tuning for every load change and application modification is a repetitive task, however, as the tuning is only valid for a specific workload and allocation rate.

Implementations of mark-and-sweep

There are at least two commercially available and proven approaches for implementing mark-and-sweep collection. One is the parallel approach and the other is the concurrent (or mostly concurrent) approach.

Parallel collectors

Parallel collection means that resources assigned to the process are used in parallel for the purpose of garbage collection. Most commercially implemented parallel collectors are monolithic stop-the-world collectors -- all application threads are stopped until the entire garbage collection cycle is complete. Stopping all threads allows all resources to be efficiently used in parallel to finish the garbage collection through the mark and sweep phases. This leads to a very high level of efficiency, usually resulting in high scores on throughput benchmarks such as SPECjbb. If throughput is essential for your application, the parallel approach is an excellent choice.

The cost of most parallel collection -- and do consider this, especially for production environments -- is that application threads cannot do any work during a GC, just like with copying collectors. Using a parallel collector that implements stop-the-world collection will have a major impact on response-time sensitive applications, especially if you have a lot of references to trace, which will happen with many live or complex data structures on the heap. (Remember that for mark-and-sweep collectors the time to free up new memory is dependent on the time it takes to trace the live data set plus the time to traverse the heap during the sweep phase.) For a monolithic parallel approach using all resources in parallel, this entire time will be a pause, and that pause corresponds to the entire GC cycle.

Concurrent collectors

A concurrent collector is a much better fit for applications that are sensitive to response time. Concurrent means that some (or most) garbage collection work is performed concurrently with the running application threads. As not all resources are used for GC, you will have the challenge of deciding when to start a garbage collection in order to allow enough time for the cycle to end. You need enough time to trace the live set and reclaim the memory before the application runs out of memory. If the garbage collection doesn't complete in time the application will throw an out-of-memory error. You don't want to do garbage collection all the time because that would consume application resources, thus impacting throughput. It can be extra tricky to keep that balance in very dynamic environments, so heuristics have been designed to determine when to start garbage collection and when to do various GC optimizing tasks and how much at a time, etc.

Thursday, 9 January 2014

Arrays

Array:

  • Array is a collection of similar type of elements that have contiguous memory location.
  • In java, array is an object the contains elements of similar data type. 
  • It is a data structure where we store similar elements. 
  • We can store only fixed elements in an array.
  • Array is index based, first element of the array is stored at 0 index.
Example: 
class Array{  
public static void main(String args[]){  
  
int a[]=new int[5];//declaration and instantiation  
a[0]=10;//initialization  
a[1]=20;  
a[2]=70;  
a[3]=40;  
a[4]=50;  
  
//printing array  
for(int i=0;i<a.length;i++)//length is the property of array  
System.out.println(a[i]);  
  
}}  

Output: 10
       20
       70
       40
       50


Advantage of Array

  • Code Optimization: It makes the code optimized, we can retrieve or sort the data easily.
  • Random access: We can get any data located at any index position.
  • Insertion, deletion and updation is easy.

Disadvantage of Array

Size Limit: We can store only fixed size of elements in the array. It doesn't grow its size at runtime. To solve this problem, collection framework is used in java.

Types of Array

  • Single Dimensional Array
                 Example:  int a[]={33,3,4,5};//declaration, instantiation and initialization  
  • Multidimensional Array
               Example:  int[][] arr=new int[3][3];//3 row and 3 column 

Wednesday, 8 January 2014

Demo program for swapping of objects

In this program we pass objects. But to swap the values we need to swap by value only.
Swapping the objects will not swap the values the object points to.

Demo: 

package date;

public class Date_Obj {

/** This is a program for swapping of objects.
* @Author Snehal
*/
int dd,mm,yy;
public Date_Obj() {
}
Date_Obj(int dt,int mth,int yr){
dd=dt;
mm=mth;
yy=yr;
}
public void swap(Date_Obj d1, Date_Obj d2) {
Date_Obj d3 = new Date_Obj();
d3.dd = d1.dd;
d3.mm = d1.mm;
d3.yy = d1.yy;

d1.dd = d2.dd;
d1.mm = d2.mm;
d1.yy = d2.yy;

d2.dd = d3.dd;
d2.mm = d3.mm;
d2.yy = d3.yy;
}
public String toString() {
return dd+" "+mm+" "+yy;
}
public static void main(String[] args) {
System.out.println("Before swap:");
Date_Obj d1 = new Date_Obj(1,1,2014);
System.out.println(d1);
Date_Obj d2 = new Date_Obj(2, 2, 2014);
System.out.println(d2);
d1.swap(d1, d2);
System.out.println("After swap:");
System.out.println(d1);
System.out.println(d2);
}

}

Output: 
Before swap:
1 1 2014
2 2 2014
After swap:
2 2 2014
1 1 2014

Access Specifiers

The access specifiers specifies accessibility (scope) of a data member, method, constructor or class.

There are 4 types of access specifiers:
  •     private
  •     default
  •     protected
  •     public


 Private: The private access modifier is accessible only within class.

Example: 
package date;


class Test {
private int number = 10;
private void display() {
System.out.println("Private Demo");
}
}

public class Demo {

/**
* @param args
*/
public static void main(String[] args) {
Test obj = new Test();
System.out.println(obj.number); // error occurs i.e. the field Test.number is not visible.
obj.display(); // error occurs i.e. The method display() from the type Test is not visible.

}

}


 Default: If you don't use any modifier, it is treated as default by default. The default modifier is accessible only within package.
Example:
Class 1: 
package date;


public class Demo {

/**
* @param args
*/
int number = 10;
void display() {
System.out.println("Private Demo");
}
public static void main(String[] args) {

}

}

Class 2: 
package test;

import date.Demo;
public class demo {

/**
* @param args
*/
public static void main(String[] args) {
Demo obj = new Demo();
System.out.println(obj.number); // The field Demo.number is not visible
obj.display(); //The method display() from the type Demo is not visible
}

}


 Protected: The protected access modifier is accessible within package and outside the package but through inheritance only. The protected access modifier can be applied on the data member, method and constructor. It can't be applied on the class.
Example: 
Class 1: 
package date;


public class Demo {

/**
* @param args
*/
protected int number = 10;
protected void display() {
System.out.println("Private Demo");
}
public static void main(String[] args) {

}

}

Class 2: 
package test;

import date.Demo;
public class demo extends Demo{

/**
* @param args
*/
public static void main(String[] args) {
demo obj = new demo();
System.out.println(obj.number);
obj.display();
}

}


 Public: The public access modifier is accessible everywhere. It has the widest scope among all other modifiers.
Example: 
Class 1:
package date;

public class Demo {

/**
* @param args
*/
public int number = 10;
public void display() {
System.out.println("Private Demo");
}
public static void main(String[] args) {

}

}

Class 2: 
package test;

import date.Demo;
public class demo {

/**
* @param args
*/
public static void main(String[] args) {
Demo obj = new Demo();
System.out.println(obj.number);
obj.display();
}

}

Tuesday, 7 January 2014

Packages

Package
  • A package is a group of similar types of classes, interfaces and sub-packages.
  • It helps Organize your classes into a folder structure and make it easy to locate and use them.More importantly,it helps improve re-usability.
  • To avoid naming conflicts packages are given names of the domain name of the company in reverse Ex :  com.guru99, com.microsoft, com.infosys etc.
  • When a package name is not specified , a class is into the default package (the current working directory) and the package itself is given no name.
  • While creating a package, care should be taken that the statement for creating  package must be written before any other import statements.

Package can be categorized in two form, built-in package and user-defined package. There are many built-in packages such as java, lang, awt, javax, swing, net, io, util, sql etc.

Advantage of Package
  • Package is used to categorize the classes and interfaces so that they can be easily maintained.
  • Package provides access protection.
  • Package removes naming collision.

package in java
Simple example of package

The package keyword is used to create a package.

    //save as Simple.java  
      
    package mypack;  
    public class Simple{  
     public static void main(String args[]){  
        System.out.println("Welcome to package");  
       }  
    }  

How to compile the Package (if not using IDE)

If you are not using any IDE, you need to follow the syntax given below:

    javac -d directory javafilename  

For example

    javac -d . Simple.java  

The -d switch specifies the destination where to put the generated class file. You can use any directory name like /home (in case of Linux), d:/abc (in case of windows) etc. If you want to keep the package within the same directory, you can use . (dot).
How to run the Package (if not using IDE)

You need to use fully qualified name e.g. mypack.Simple etc to run the class.
To Compile: javac -d . Simple.java
To Run: java mypack.Simple

Output:Welcome to package







The -d is a switch that tells the compiler where to put the class file i.e. it represents destination. The . represents the current folder.

How to access package from another package?

There are three ways to access the package from outside the package.
  •     import package.*;
  •     import package.classname;
  •     fully qualified name.

Using packagename.*

If you use package.* then all the classes and interfaces of this package will be accessible but not sub-packages.
The import keyword is used to make the classes and interface of another package accessible to the current package.

Example of package that import the packagename.*

    //save by A.java (java class one) 
      
    package pack;  
    public class A{  
      public void msg(){System.out.println("Hello");}  
    }  

    //save by B.java (java class two) 
      
    package mypack;  
    import pack.*;  
      
    class B{  
      public static void main(String args[]){  
       A obj = new A();  
       obj.msg();  
      }  
    }  

Output:Hello

Using packagename.classname

If you import package.classname then only declared class of this package will be accessible.
Example of package by import package.classname

    //save by A.java  (java class one) 
      
    package pack;  
    public class A{  
      public void msg(){System.out.println("Hello");}  
    }  

    //save by B.java  (java class two) 
      
    package mypack;  
    import pack.A;  
      
    class B{  
      public static void main(String args[]){  
       A obj = new A();  
       obj.msg();  
      }  
    }  

Output:Hello

Using fully qualified name

If you use fully qualified name then only declared class of this package will be accessible. Now there is no need to import. But you need to use fully qualified name every time when you are accessing the class or interface.

It is generally used when two packages have same class name e.g. java.util and java.sql packages contain Date class.
Example of package by import fully qualified name

    //save by A.java  (java class one) 
      
    package pack;  
    public class A{  
      public void msg(){System.out.println("Hello");}  
    }  

    //save by B.java  (java class two) 
      
    package mypack;  
    class B{  
      public static void main(String args[]){  
       pack.A obj = new pack.A();//using fully qualified name  
       obj.msg();  
      }  
    }  

Output:Hello

If you import a package, all the classes and interface of that package will be imported excluding the classes and interfaces of the sub-packages. Hence, you need to import the sub-package as well.

How to send the class file to another directory or drive?

This can be done using classpath
Classpath is a parameter—set either on the command-line, or through an environment variable—that tells the Java Virtual Machine or the Java compiler where to look for user-defined classes and packages.

For example:
how to put class file in another package

    //save as Simple.java  
      
    package mypack;  
    public class Simple{  
     public static void main(String args[]){  
        System.out.println("Welcome to package");  
       }  
    }  

To Compile:
e:\sources> javac -d c:\classes Simple.java
To Run:
To run this program from e:\source directory, you need to set classpath of the directory where the class file resides.
e:\sources> set classpath=c:\classes;.;
e:\sources> java mypack.Simple

Another way to run this program by -classpath switch of java:
The -classpath switch can be used with javac and java tool.
To run this program from e:\source directory, you can use -classpath switch of java that tells where to look for class file. For example:
e:\sources> java -classpath c:\classes mypack.Simple

Output:Welcome to package

Friday, 3 January 2014

Static Variable and this keyword

Static is a keyword in java. Static can be used in three scenarios:
1.     Static variables
2.     Static methods
3.     Static blocks of code
Static Variable(Class Variable):  

  • It is a variable which belongs to the class and not to object(instance).
  • Static variables are initialized only once , at the start of the execution . These variables will be initialized first, before the initialization of any instance variables
  • single copy to be shared by all instances of the class
  • A static variable can be accessed directly by the class name and doesn’t need any object
  • Syntax : <class-name>.<variable-name>
Static method:
  • It is a method which belongs to the class and not to the object(instance) 
  • A static method can access only static data. It can not access non-static data (instance variables) 
  • A static method can call only other static methods and can not call a non-static method from it.
  • A static method can be accessed directly by the class name and doesn’t need any object .
  • Syntax : <class-name>.<method-name>
  • A static method cannot refer to “this” or “super” keywords in anyway.
  • A static method can have non static data.
Static block:
  • static block helps to initialize the static data members, just like constructors help to initialize instance members.
  • The static block, is a block of statement inside a Java class that will be executed when a class is first loaded in to the JVM.

    this keyword: 
    • “this” is a reference to the current object, whose method is being called upon.
    • You can use “this” keyword to avoid naming conflicts in the method/constructor of your instance/object.
    • It is a hidden reference.
    Example: In this program even though swap function is called the numbers will not be swapped.
     It is because we are using the same name as that of global variables and local variables.
      


    public class Swap {

    /**
    * This is a program for swapping of two integer numbers. 
    * @Author Snehal
    */
    int num1=10 ;
    int num2=20;

    public void swap(int num1, int num2)
    {
    int temp=0;
    temp = num1;
    num1 = num2;
    num2 = temp;
    }
    public static void main(String[] args) {
    Swap obj = new Swap();
    System.out.println(obj.num1+"  "+obj.num2);
    obj.swap(10,20);
    System.out.println(obj.num1+"  "+obj.num2);
    }

    }

    Output: 10 20
                 10 20





     If  here we have had used other names than num1, num2 in swap function then numbers will be swapped.

    public class Swap {

    /**
    * This is a program for swapping of two integer numbers. This program provides the use of this keyword.
    * @Author Snehal
    */
    int num1=10 ;
    int num2=20;

    public void swap(int num, int numbr) 
    {
    System.out.println(num+"  "+numbr);// numbers passed are 10 20
    int temp=0;
    temp = num;
    num = numbr;
    numbr = temp;
    System.out.println(num+"  "+numbr);// after swapping prints 20 10
    }
    public static void main(String[] args) {
    Swap obj = new Swap();
    //System.out.println(obj.num1+"  "+obj.num2);
    obj.swap(10,20);
    }

    }
    Output: 10 20
                20 10















    Example of
    this keyword: 
    public class Swap {

    /**
    * This is a program for swapping of two integer numbers. This program provides the use of this keyword.
    * @Author Snehal
    */
    int num1=10 ;
    int num2=20;

    public void swap(int num1, int num2)
    {
    int temp=0;
    temp = num1;
    this.num1 = num2;
    this.num2 = temp;
    }
    public static void main(String[] args) {
    Swap obj = new Swap();
    System.out.println(obj.num1+"  "+obj.num2);
    obj.swap(10,20);
    System.out.println(obj.num1+"  "+obj.num2);
    }

    }

    Output: 10 20
                 20 10