Friday 6 April 2012

Java Strings

String Concept

String is created in 2 ways in Java.

1. String as an object using new keyword
2. String as object using "" ie, double quotes

1. String as an object using new keyword:

        To represent  String as an object we use 'new' keyword as shown below.

           String s1 = new String("hello");
          
           Firstly we need to understand that String has separate memory location inside heap known as String Pool which is divided into 2 areas.
           1. String Constant Pool (SCP)
           2. String Non Constant Pool (SNCP)

           Now when we are creating a String object, an instance is created inside String Non Constant Pool area and the reference (s1) will be pointing to this location and also  1 more String object will be created inside String Constant Pool but the reference (s1) will not be pointing to this location. Both the memory areas has "hello" as String value.
                                                                  :
                                                                  :
s1  --------> string value  = "hello"              :           string value  = "hello"
                    String Non Constant Pool    :       String Constant Pool
                                                                  :                                        

2. String as object using "" ie, double quotes:

          Now when we are creating a String literal as shown below
         
          String s2 = "hello123";

          First the compiler will check is there any value with "hello123" in String Constant Pool, if there is no value then it will create a new value and s2 will point to that value, if there is a value matching then no new value will be created and s2 will point to that existing value only.

                                                             :
s1  --------> string value  = "hello"         :      string value  = "hello"
                                                             :       string value = "hello123"   <-------- s2
                                                             :
           String Non Constant Pool        :      String Constant Pool


         Now when we are creating 2 String literal with value = "hello" as shown below
         
          String s3 = "hello";
          String s4 = "hello";

          First the compiler will check is there any value with "hello" in String Constant Pool, as there is a value matching then no new value will be created and both s3, s4 will point to the existing value only.

                                                             :
s1  --------> string value  = "hello"         :      string value  = "hello"        <-------- s3, s4
                                                             :       string value = "hello123"   <-------- s2
                                                             :
            String Non Constant Pool       :      String Constant Pool


          Now when we are creating a new String object with value = "hello world" as shown below
         
          String s5 = new String("hello world");

          A new object will be created in Heap area and the reference (s5) will be pointing to this location, and also a String literal will be created in String Constant Pool as this value is not already existing in SCP.

                                                                :
s1  --------> string value  = "hello"            :      string value  = "hello"            <-------- s3, s4
s5  --------> string value  = "hello world"  :       string value = "hello123"      <-------- s2
                                                                :       string value = "hello world"   
                                                                :
            String Non Constant Pool               :      String Constant Pool


Analyze your String knowledge:

String s1 = "Hello World";
String s2 = "Hello World";

s1 == s2  -------> true (because both are pointing to same memory location)
s1.equals(s2) -------> true (string value is same)
String s3 = new String("Hello");
String s4 = new String("Hello");
String s5 = new String("Hello World");

s3 == s4  -------> false (because both are pointing to different memory location)
s1 == s5  -------> false (because both are pointing to different memory location)

s3.equals(s4) -------> true (string value is same)
s1.equals(s5) -------> true (string value is same)

String s6 = "Hello" + " World";
String s7 = "Hello";
String s8 = " World";
String s9 = s7 + s8;
String s10 = s7 + " World";

s1 == s6    -------> true (because both are pointing to same memory location)
s2 == s9    -------> false (because both are not pointing to same memory location)
s2 == s10  -------> false (because both are not pointing to same memory location)

s1.equals(s6)     -------> true (string value is same)
s2.equals(s9)     -------> true (string value is same)
s2.equals(s10)   -------> true (string value is same)

Important Note:
1. String Constant Pool will not contain any duplicate values.
2. From the above concept you can understand that String is Immutable i.e., as the value changes by any reference in SCP all other references which are pointing to that location will also get changed automatically which is known as Immutability.
3. == operator is used to check the memory location (address) of any 2 objects of same type or atleast sub class of other object which is used to compare, otherwise it throws compile time error.
4. equals() method is overriden in String class in order to compare the String values for any given 2 Strings.
5. String objects are immutable (ie., object is created as final implicitly) that is why when we are trying to change or modify the string value it will create a new object with same reference and then assigns new value to it.
Advantages:         High performance
Disadvantages:    Immutability

Thursday 5 April 2012

Method Overriding

2. Dynamic Polymorphism (Method Overriding):
          Defining a method with same method signatures in sub class is known as Method Overriding.

        Class SuperClass{
                 public String override(int i, String s) {
                      System.out.println("SuperClass Override method called");
                 }                
         }

        Class SubClass extends SuperClass{
                 public String override(int, String s) {
                      System.out.println("SubClass  Override method called");
                 }
         }


        Class Test{
                 public static void main(String[] args) {
                      SuperClass sc = new SubClass ();
                      sc. override(1, "hello");
                 }
         }

Output:
SubClass  Override method called

Conditions for method overriding are:
1.Firstly, we need to inherit the super class members (inherits variables and methods)  in order to override the method in sub class.
2. SubClass method signatures should be same to that of SuperClass method.
3. method return types must be same in both the methods.
4. If SuperClass method throws any exception the SubClass method too should throw the same exception or its sub class type exception

Important Note:
1. Method return type is part of a Overriding.
2. SubClass method access modifier should be atleast same type or more widening to that of SuperClass method.

private > default (no modifier or package level) > protected > public
Above are the access modifiers widening from left to right.

3. We can not override private method as they are not inherited into sub class.
4.  In above program we are creating a SubClass object and holding it in a SuperClass reference. ie., super class reference referring to a sub class object.
now when we call sc.override(1, "hello") method the SubClass method will be called rather than SuperClass method.

5. Here SuperClass reference will invoke the SubClass method. When we are trying to invoke any method specific to SubClass only. i.e. method not present  in SuperClass, it will give compile time error.

6. We can not override static methods, by doing so it leads to a new concept called as Method Hiding.
Here in method hiding when we call sc.override(1, "hello") method the SuperClass method will be called rather than SubClass method. ie., SubClass method will be hidden.

7. final methods can not be overriden. To avoid overriding use "final" keyword before return type in the super class method.


But why overriding is considered as dynamic polymorphism?
     Because the method invocation ( sc.override(1, "hello") ) call is not binded to the respective method at compile time itself by the compiler as compiler doesn't know which class method to invoke and leaves it to JVM to invoke and at runtime JVM invokes SubClass method. Here as the binding is happening at run time it is also know as late binding or dynamic binding or run time binding.

Method Overloading

Basically polymorphism is classified in two types in Java.

1. Static Polymorphism
2. Dynamic Polymorphism

1. Static Polymorphism (Method Overloading):
          Defining 2 methods with same name but different method signatures in a class is known as Method Overloading.

        Class MethodOverload {
                 public void overload() {
                      System.out.println("Overloaded method");
                 }
                 public int overload( int i) {
                      System.out.println("Overloading method" + i);
                      // requirement specific logic is written as above line
                      return i;

                 }
                 public static  int overload(String s) {
                      System.out.println("Overloading method" + s);
                      // requirement specific logic is written as above line
                      return s;

                 }
         }

        Class Test{
                 public static void main(String[] args) {
                      MethodOverload   load = new MethodOverload();
                      load.overload();
                      load.overload(5);
                      load.overload("hello");
                 }

         }

Output:
Overloaded method
Overloading method5
Overloading methodhello

Conditions for method overloading are:
1. Atleast method arguments should be different if you are using a single argument (as above).
2. Atleast method arguments order should be different if there are more than 1 argument.
3. Atleast number of method arguments should be different.

Important Note:
1. Method return type is not a part of Overloading.
2. Access Modifiers are also not a part of Overloading.
3. We can have static methods overloaded too.


But why overloading is considered as static polymorphism?
     Because the method invocation call is binded to the respective method at compile time itself by the compiler. Here as the binding is happening at compile time it is also know as early binding or static binding or compile time binding.