OCPJP Guide

Happy learniing some java concept as well as algorithms and programs often asked for interview and practical application. For Algos follow this link.


Algorithms and Programs

class

A template that describes the kinds of state and behavior that objects of its type support.

Here we have a look at different members that can be defined in the class.

                package packagename; //must be first statement, if exist
                import java.util.*;       //if package doesnt exist, it must be the first statement
                
                public class Sample             
                {
                int age;   //instance variable
                public static int count;   //static variable
                
                public Sample()   //default constructor
                {
                
                }
                
                static{ count=5;  }   //static block
                { age=4;   }         //initialization block
                
                
                public int getAge()        //public method
                {
                return age;   //return statement
                }
                
                public void setAge(int ageFromCaller)   //public method
                {
                age=ageFromCaller;     //ageFromCaller is local variable,since its scope is within methods
                }
                
                public static void main(string args[])    //static method
                {
                
                for(int i=0;i<5;i++)
                {
                
                System.out.println(""+i);   //i is block level variable, since its scope is within the loop
                }
                
                
                }
                
                
                }
                
                

object

object is an instance of class.object will have its own state, and access to all of the behaviors defined by its class.

Identifiers

All the component in java such as Variables,Classes and Methods etc needs Names.
In Java these names are called identifiers,

Rules for identifiers


Identifiers must start with a letter, a currency character ($), or a connecting character such as the underscore ( _ ). Identifiers cannot start with a number!
After the first character, identifiers can contain any combination of letters, currency characters, connecting characters, or numbers.
You can't use a Java keyword as an identifier.
Identifiers in Java are case-sensitive;

				Examples of legal identifiers


int _a;
int $c;
int ______2_w;





    			
				Examples of illegal identifiers


int :b;
int -d;
int e#;
int .f;
int 7g;





    			

Keywords

They are reserved by java and cannot be use as identifier:

sry

    			

Datatypes

you can create variables of various datatypes that are supported in java

Range of various primitive datatypes

sry
    			

Variables

It is a programming element whose value keeps on changing during the course of execution.

2 Types of variables in java.

Primitive:
A primitive can be one of eight types: char, boolean, byte, short, int, long, double, or float.

eg:primitive
int age;
double area;
eg:reference Employee d; Object o;

Casting

There are 2 types of primitive casting, implicit and explicit.

Casting is the process of converting value of 1 datatype to another.

implicit: its is the process of fitting small number in large container datatype, like int to long, float to double.

implicit casting will be done by compiler, so we need not take care of it.


explicit: it is the process of fitting large number in small container datatype, i.e long to int, double to int

We will understand them better in below topic.

          //int to long
            int i=45;
          long l=i;   //implicitly compiler produces long l=(long)i.
            System.out.println(l);
          
          

now let's check the example of explicit casting.

          long l=45;
          int i=l;
          System.out.println(i);
          

output:possbile losy conversion from long to int.

We can solve this by cast.

          long l=45;
          int i=(int)l;
          System.out.println(i);
          
          

output:45


Example of float to int conversion

          float f=45.12f;
          int i=(int)f;    //required cast since converting will lead to loss of .12 from 45.12 
           System.out.println(i);
          

output:45

We will also see some examples in below topic.

Literal values

Integer literal

integer literal can be represented in 3 ways.

Decimal Literal.

Octal Literal, which is represented by placing 0 in front of the number.

octal consist of following numbers.

0,1,2,3,4,5,6,7

Hexadecimal literal, which is represented by placing 0x in front of the number.

hexadecimal consist of foll numbers

0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f

        int size=48; //decimal
        int size=010; //octal i.e value is 8
        int size=0xabcd;//hexadecimal
        

Float literals

Bydefault all floating point literals are defined as double in java .

so something like this should ring bell in your mind.

float cm=3.5 //compiler error:possible loss of precision

float cm=3.5f or float cm=3.5F is a right way to go.


double literal

double d=35.456d // appending d is optional.

double d=35.456 //its fine,no problem.


Character literal

char c='a';

char c='\u0fff'; //just prefix \u

character are implicitly convertible to integer.

char c=99; //number uptil range of char can be assigned.i.e(65535)

char c=65800; //error:possible loss of precision.

char c=(char)65800; //can be solved by explicit cast.


boolean literal

boolean b=true; //legal

boolean b=0; //illegal in java, but legal in other lang such as c++.

String literal

String is not primitive, and it is not an array of character like in c++.

String is an class in java, yes you heard it right an final class.

String s="hello";

playing with bytes

byte is implicitly convertibe to int.

byte b=14; or byte b=(byte)45; //casting is done implicity by compiler.

now here is important part.

add 2 bytes,multiply 2 bytes,divide 2 bytes, everything will result into integer.
        byte a=24;
        byte b=9;
        int c=b+c;  
        
above code will work, but what if you wrote something like this.
        byte a=10;
        byte b=5;
        byte c=a+b; //compiler error
        
but if you still persist to get the result in byte, then solution is to cast it.
        byte c=(byte)(a+b);
        

have a look at another point.

        byte b=5;
        b+=5; //should this give compiler error?
        

as per earlier point adding 2 byte will result into integer and if you assign result to byte variable, it will not compile.

in this case compiler help you.

compiler will do the casting for you.

hence your code becomes.

        byte b=5;
        //this casting will be added by compiler
        b=(byte)(b+5);
        

Assigning a value which is out of range for variable of that type.

        byte b=130;
        

output:compiler error: possible lossy conversion from int to byte.

Since range of byte is till -128 to +127.

so to solve this, we need explicit casting.

        byte b=(byte)130;
        

output: -126

needs explanation for output right!!!

an integer is 4byte, i.e 32 bit while byte is 8bit.

32 in integer is represented as:

00000000 00000000 00000000 10000010

to fit this big number in 8 bits, left 24 bits are removed

now after truncatiing, we end up with this number 10000010.

since left most bit is used for sign representation:

1 -negative 0 +positive

So system always stores negative numbers in 2's complement form

1's complement will be 01111101 and then adding 1 to it we get

01111110. i.e 126 and 1 in the leftmost bit makes it -126.

quite a explanation huh!!! you need to understand 2's complement for better understanding of this.

Access controls

There are 4 level of access controls
1.private
2.default
3.protected
4.public

A class can use only 2 access controls:
public and default.

Default

Default protection is what you get when you don't type an access modifier in the member declaration.
A default member may be accessed only if the class accessing the member belongs to the same package, whereas a protected member can be accessed (through inheritance) by a subclass even if the subclass is in a different package

private

The private member can only be accessed by the class in which they are declared.

protected

The protected members can be accessed by the class that extends the class, whether it is in the same package or different.

public

All classes can access public members.

sry
    			

All these access specifiers plays important role in questions related to inheritance in exam.

local variables and access specifiers

local variables are the ones that are declared inside methods.

Warning! access specifier cannot be applied to local variables.
class Fax {
void doPrint() {
private int x = 7;  //will not compile.
this.doMore(x);
}
}
    			

so be sure to catch these kind of error.

Non access specifiers

we'll have a look at non access specifiers.

final

1.prevent overriding of method

class SuperClass{
public final void printX() {
System.out.println("superclass method.");
}
}

class SubClass extends SuperClass{
public void printX() { // Try to override the final
System.out.println("subclass method.");
}
}

    			

Attempting to compile the preceding code gives us compiler error:
It's legal to extend SuperClass, since the class isn't marked final, but we can't override the final method printX(), :

2.prevent class to be subclassed. or class cannot be inherited.


class final SuperClass{
public void printX() {
System.out.println("superclass method.");
}
}

class SubClass extends SuperClass{  // Try to inherit class which is marked with final keyword.
public void printX() { 
System.out.println("subclass method.");
}
}

    			

Attempting to compile the preceding code gives us compiler error.


3.used to create constant variable. i.e whose value cannot be changed once assigned during initialization.

class SampleClass{Class{
final int copies=2;
public void printX() {
copies=3; 
System.out.println("SampleClass method.");
}
}
    			

Attempting to compile the preceding code gives us compiler error.


But wait there is an exception to it. if you not initialize during declaration then you can also assign the value to final variable in constructor.


this is known an blank final variable.

class SampleClass{Class{
final int copies; // blank final variable

SampleClass()
{
copies=2;
}

public void printX() {
copies=3; 
System.out.println("SampleClass method.");
}
}
    			

abstract

An abstract method, is an method who does not have body.
A class which contain abstract method should also be marked abstract. it is the responsibilty of class who is inheriting abstract class, to provide implementation for it. We'll cover abstract in more details ahead.

class abstract SampleClass
{
public void abstract getCalculation();  //it doesnt have body
}

    			

check this case given below

class SampleClass
{
public void abstract getCalculation();  //it doesnt have body
}

    			

above class will give compiler error,Since SampleClass should be declared abstract.


synchronized

An synchronized method, is an method which can be accessed by only one thread at a time.
We'll cover synchronized in more details ahead in threads. so for now just remember the syntax.

class SampleClass extends thread
{
public void synchronized getPi()
     {
            return 3.14;
     }
}

    			

static

static specifier specify that the member belongs to a class rather to a specific object. so no matter how many object you create of a class, there will be only one copy of static member is created.
All the instance for same class share the same value for static variable.
You can create Static:
method.
variable.
static class nested within each other(more on this in inner class chapter.
static initailization block.


Have a look at this eg:

class SampleClass 
{
static int count;
String name;
int age;

public String getname(){
return name;
                    }
                    
public static int getCount()
{
return count;
}


public static void main(String args[])
{
SampleClass s1=new SampleClass();
SampleClass s2=new SampleClass();
}

}

    			

Memory Structure created by above code is.
**************************************SampleClass****************************
*                                                                           *
*                     int count                                             *         
*                      getCount()                                           *          
*                                                                           *
*                                                                           *
*                                                                           *
*                                                                           *
*        S1                        S2                                       *    
*     ***************         *******************                           *                                    
*     * String name *         *    String name  *                           *
*     *  int age    *         *    int age      *                           *                  
*     *   getName() *         *     getName()   *                           *                      
*     ***************         *******************                           *                                  
*                                                                           *
*                                                                           *
*                                                                           *
*                                                                           *
*                                                                           *
*                                                                           *
*****************************************************************************

    			

The above structure illustrates that Each Object S1 and S2 has separate methods getName() and separate variables age,name. the values for age and name will differ from instance to instance depending on operation perform on it.
But They Both have common is Count variable and getCount() method.


native

An native method, is an method which is implemented in platform independant platform.
As for exam, no question are asked related to it,so you should only know above description.


strictfp

Different processor has different range of floating point precision. Hence to adhere to IEEE754 standard of floating point precision we must use strictfp


transient

By marking instance variable as transient, that variable will not be serialiazed, i.e its value will not be persisted while serializing instance.
We'll learn more in Serialization chapter.


volatile

the volatile keyword in Java is used as an indicator to Java compiler and Thread that do not cache value of this variable and always read it from main memory

Enum

Enum can be used where we want value of variable to be restricted to certain values.


e.g enum week{SUN,MON,TUE,WED,THU,FRI,SAT}; //semi-colon is optional
According to sun's convention all constant should be capital,hence it is a good practice and not mandatory for all enum constant to be capital.
Warning!! Enum should not be declared inside a method.
Enum can be declared outside class, inside class.but not inside method.
enum Week{SUN,MON,TUE,WED,THU,FRI,SAT}   //only public and default specifiers for enum outside class

class SampleClass 
{
Week day;

public static void main(String args[])
{
day=Week.SUN;
//to get the enumerated list of all constant use values()
for(day:Week.values())
{
System.out.println("values:"+day);
}

}

}

    			

Enum inside an class and referring it from another class


  class EnumSample
  {
  enum Week{SUN,MON,TUE,WED,THU,FRI,SAT}; 
  Week day;
  
  
  }

class SampleClass 
{


public static void main(String args[])
{
EnumSample es=new EnumSample();
es.day=EnumSample.Week.SUN;    //enclosed classname should be used     


}

}

    			

While using the enum enclosed inside another class, classname should precede


Enum can also have constructor,variables,method.

Warning!! Constant should be first declared in enum body then other things come.
  
  enum Week{SUN(4),MON(4),TUE(4),WED(4),THU(4),FRI(4),SAT(4);
  int whichWeek;
  Week(int whichweek)  //constructor
  {
  this.whichWeek=whichWeek;
  }
  
  public int getWhichWeek()
  {
  return whichWeek;
  }
  
   public int setWhichWeek(int whichWeek)
  {
  this.whichWeek=whichWeek;
  }
  
  
  };   //enum end 


class SampleClass 
{
Week day;

public static void main(String args[])
{
SampleClass sc=new SampleClass();
 sc.day=Week.SUN;       
System.out.println("week:"sc.day+"\n whichweek:" sc.day.getWhichWeek());

}

}

    			

Now, you can also override method for specific Constant in enum, well i'll just show you the code of enum body.

enum Week{SUN(4),MON(4),TUE(4),WED(4),THU(4),FRI(4),SAT(4){
 
 public int getWhichWeek()   //overriding method for SAT constant
  {
  
  return 5;  
  }
  


};
  int whichWeek;
  Week(int whichweek)  //constructor
  {
  this.whichWeek=whichWeek;
  }
  
  public int getWhichWeek()
  {
  return whichWeek;
  }
  
   public int setWhichWeek(int whichWeek)
  {
  this.whichWeek=whichWeek;
  }
  
  
  };  

in the above code method getWhichWeek() is been overridden for SAT constant.

Operators

Relational operators

six relational operators (<, <=, >, >=, ==, and !=) we will cover for the exam.


Relational operators always return boolean value, i.e true or false.

operator meaning
==Equal to
!=Not Equal to
<less than
<=less than or equal to
>greater than
>=greater than or equal to
instance ofto check whether object is of particular type.

Equality

There is often confusion between == operator and equals method of string.


public static void main()
{
String x=new String("hello");
String y=new String("hello");

if(x==y)
{
System.out.println("== succeed");
}
if(x.equals(y))
{
System.out.println("equals() succeed");
}



}
    			

In this case output will be:
equals() succeed
This is because == opearator checks the referance of the object, i.e bit pattern
As String is a class in java, two diff object are created with separate memory allocation, although there value is same.
Hence == operator checked the reference of the object, which are different. While equals() check the value of 2 variable, which was same, hence it return true.
further on equals() in String chapter.

"==" exam catch

beware of the "==" used in if statements


public static void main()
{
int x=3;
 
if(x=3)     //this is not comparing but assigning value,
//hence if condition does not evaluate to boolean value, compiler error
{
System.out.println("fooling you");
}




}
    			

output: compiler error

If condition should always evaluate to boolean value.

Arithmetic operator

operator meaning
+addition
-substraction
*multiplication
/division
%modulus

Since we all know these operators, they dont need great explanation.


Compound operator

operator meaning example evaluation
+=Compound additiona+=ba=a+b
-=Compound substractiona-=ba=a-b
*Compound multiplicationa*=ba=a*b
/=Compound divisiona/=ba=a/b
%=Compound modulusa%=ba=a%b

increment and decrement operator

++i/--i prefix
i++/i-- postfix
prefix means first increment/decrement and then use
postfix means first use and then increment/decrement.
public static void main(String args[])
{
int i=0;
System.out.println("value of prefix i: "+(++i));
System.out.println("value of after prefix i: "+(i));

System.out.println("value of postfix i: "+(i++));
System.out.println("value of after postfix i: "+(i));



}



output: value of prefix i:1
value of after prefix i:1
value of postfix i:1
value of after prefix i:2


Did you observe the difference.
Watch the use of increment and decrement operator with respect to final variable, as final variable value won't change
it gives error.
public static void main(String args[])
{
final int x=5;
x++;  //will produce error.
System.out.println("value of x"+x);


}

ternary operator


Similar to if statement its evaluates boolean condition.


It can be used to assign value to variable like
variable=(boolean expression)?if true assign these value: else assign these value
e.g
public static void main(String args[])
{
int age=19;
String stageOfLife;  // had to wonder,what should i name these variable.

stageOfLife=(age>18)?"adult":"kid";
System.out.println("stageOfLife: "+stageOfLife);


}


()parenthesis are optional.
if boolean statement is right then assign 1st value or else assign 2nd value .
I hope you got it.


Logical operator

operator meaning
&logical AND(Bitwise)
|logical OR(Bitwise)
^logical EX-OR(Bitwise)
&&short-circuit AND
||short-circuit OR
!logical not

understanding logical operators....
Working of logical AND
A B A&B
TrueTrueTrue
TrueFalseFalse
FalseTruefalse
FalseFalseFalse
A B A&B
111
100
010
000

Working of logical OR
A B A|B
TrueTrueTrue
TrueFalseTrue
FalseTrueTrue
FalseFalseFalse
A B A|B
111
101
011
000

Working of logical EX-OR
A B A^B
TrueTrueFalse
TrueFalseTrue
FalseTrueTrue
FalseFalseFalse
A B A^B
110
101
011
000

short-circuit logical operator

&& short-circuit AND || short-circuit OR

you can consider short circuit operator a bit lazy operator (but smart).Like all the good programmer!


As we know AND operator requires both the boolean expression evaluates to true. but there is some difference between the way the expression are evaluated in && and &
well same goes for || and |.

lets checkout in the foll example.
class SampleClass
{
int x=7;
    public static void main(String args[])
    {
    //using short hand operator
    SampleClass sc=new SampleClass();
    if(isEven(sc.x)& isGreater(sc.x))
    {
    System.out.println("yup its even and greater than 5!!");
    }
    
    }
    
    

      public static boolean isEven(int z)
    {
    if(z%2==0)
    {
    System.out.println("even number");
    return true;
    }
    else
    {
    return false;
    }
	}
    public static boolean isGreater(int z)
    {
    if(z>5)
    {
    System.out.println("greater number");
    return true;
    }
    else
    {
    return false;
    }
	}


}


output: greater number
yup its even and greater than 5!!

& evaluates both the expression.

Now same example using &&
class SampleClass
{
int x=7;
    public static void main(String args[])
    {
    //using short hand operator
    SampleClass sc=new SampleClass();
    if(isEven(sc.x)&& isGreater(sc.x))
    {
    System.out.println("yup its even and greater than 5!!");
    }
    
    }
    
    

      public static boolean isEven(int z)
    {
    if(z%2==0)
    {
    System.out.println("even number");
    return true;
    }
    else
    {
    return false;
    }
	}
    public static boolean isGreater(int z)
    {
    if(z>5)
    {
    System.out.println("greater number");
    return true;
    }
    else
    {
    return false;
    }
	}


}

Output:


Well output is blank, Why SOP statement in isGreater() function not executed?
&& evaluates 1st expression and if it is false, then it doesnt bother for evaluating second expression.

same is the case for || and | operator
|| will evaluate 1st expression, if its is true, it will not bother for 2nd expression.
whereas | will evaluate both expresiion even if 1st expresiion is true.

int x = 5;
if(++x > 5 || ++x > 6) z++; // x = 7 after this code

int x = 5;
if(++x > 5 | ++x > 6) z++; // x = 8 after this code


^ EX-OR

It requires one operand to be true while other to be false
int x = 7;
if((x > 5) ^ (x < 5)) x++; // x = 8 after this code

int x = 7;
if((x > 5) ^ (x > 5)) x++; // x = 7 after this code


! NOT operator

It is used to invert the resulting expression.

if(!(2>3))
{
System.out.println("inside If");
}

output:inside If


in this case 2 > 3 evaluate to false, ! operator will invert the resulting expression, hence conditon in if statement now become true


Arrays

Array is a group of element of the same type.

Arrays are object i java that store multiple variables of the same type.

Arrays can hold either primitives or object references.

Declaring Array

Arrays are declared by stating the type of element, then followed by square brackets[].Square brackets can be to the left or the right of the identifier.

    //arrays of primitives
    int a[];
    int[] a;
    //arrays of references
    Thread t[];
    Object o[];
    

now let see illegal ways of declaring arrays.

    int a[4]; //never include size while declaring array, it gives compiler error
    

Constructing Array

Simple way of initializing array is using new keyword.

    int marks[];  //declaration
    marks=new marks[5]; //constructing
    

We can also declare and constructing in 1 line

    int marks[]=new marks[5];
        

We can also construct and initialize without using new keyword

    int marks[]={1,2,3};
    

Passing array to method

    class marks
    {
    public static int total;
    public static void main(String arg[])
    {
        int marks[]={45,65,80,56};
        total(marks);
    
    }
    
    public static void total(int marks[])
    {
   
        for(int i=0;i<marks.length;i++)
        {
        total+=marks[i];
        }
        System.out.println("Total marks:"+total);
    }
    }
    

output:246


Multidimensional array

Multidimensional arrays can be defined as arrays of array.

two dimensional array is like a table structure.

syntax

    int [][]data= new int[3][2];
    

the above data[] is 3rows and 2 columns in dimensions.

its structure can be assume like this.

      0 1   
    0[][]
    1[][]
    2[][]
    //Remember arrays are zero-based i.e start first index with zero.
    

Jagged array

we can make 2 dimensional array with variable columns for each row.

its is an array that is collection of group of arrays.

Syntax

     int [][]data= new int[3][];
    

so, now we have 2 dimensional array with 3 rows but don't know the columns for each row.

This kind of arrays can be constructed like this.

      int [][]data= new int[3][];
      data[0]=new int[2]; //1st row with 2 columns
      //initializing values to 1st row array
      data[0][0]=4;
      data[0][1]=5;
      data[1]=new int[3];
      data[1][0]=6;
      data[1][1]=7;
      data[1][2]=8;
      data[2]=new int[1];
      data[2][0]=9;
    

Structure formed by above code is represented below.

      0  1  2   
    0[4][5]
    1[6][7][8]
    2[9]
    

I hope, you now have clear idea about multidimensional array.

Shortcut syntax with multidimensional arrays

    int[][] data = {{5,2,4,7}, {9,2}, {3,4}};
    

size of each row is derived from number of items in {} braces seperated by comma.


Anonymous array

it is another syntax of creating arrays.

    int[] data= new int[] {1,2,3};  //be cautious about this syntax, as in normal case size should be mentioned while constructing array.
    

in this syntax, we dont specify the array's size in declaration, but size is derived from numberof items in braces{}.


Array with references object.

If array is declared of certain class type then,it can contain objects of its subclass.

in case of interface type, we can put the object of its implementer class.

    class person
    {
    
    }
    class employee extends person
    {
    
    }
    class Sample
    {
    public static void main(String args[])
    {
    person []p={new person(),new employee()}; //this is legal.
    }
    }
    

lets check the example of array which is interface type.

    interface fish
    {}
    class turtle extends fish
    {}
    
    class Sample
    {
      public static void main(String args[])
    {
    fish []f={new turtle(),new turtle()}; //this is legal.
    
    
    }
    
    
    }
    

remember adding new fish() will not work, since we cannnot create object of interface.


next question arise is can we assign 1 array reference to another??

Answer is YES, we can,but it must of same type.

    int a[]={1,2,3,4};
    int b[]=a;   //this is legal
    
    

can we assign 2d array to another 2d array of same type?

Answer is yes.

    int a[][]={
{1,2,3},{4,5,6},{7,8,9}
                };
                int b[][]=a;  //this is legal
    

so now let see what's illegal.

Assigning array of different type.

     int a[]={1,2,3,4};
    long b[]=a;   //this is illegal
    
    

Compiler error:incompatible types,cannot convert int to long.


next case is can we assign 2d array to 1d array of same type.

Answer is no

    int a[][]={
{1,2,3},{4,5,6},{7,8,9}
                };
                int b[]=a;  //illegal
    

compiler error:incompatible types.

Methods of array class

All the methods of array calss are static, so we can call it directly like Arrays.methodname().

static void sort(array)

This method takes an array as argument and sort it ascendingly.

    class Sample
    {
    public static void main(String args[])
    {
          int a[]={4,3,2,1};
            System.out.println("Array before sorting");
        for(int i:a)
        {
            System.out.println(""+i);
        }
        System.out.println("Array after sorting");
        Arrays.sort(a);
         for(int i:a)
        {
            System.out.println(""+i);
        }
    
    
    
    }
    
    
    }
    
    

output:

Array before sorting 4 3 2 1 Array after sorting 1 2 3 4

Control statements

If else statement

Syntax

                if(boolean expression )
                {
                statement1;
                statement2;
                }
                else
                {
                statement3;
                statement4;
                }
				

explanation:if boolean expression evaluates to true,then execute statements in if block, or else execute statements in else block.


If you have only one statement to execute then, parenthesis are optional.


Syntax:
                if(boolean expression )
                statement1
                else
                statement2
				

although it is a bad practice, but exam does have question like these.

                if(3>2 )
                System.out.println("3 is greater than 2");
                System.out.println("2 is smaller than 3");
                
				

in this case 2nd print statement will get printed but not as a part of if block but as a program flow.


let have another confusing if else statement example:
        if(x>4)
        if(x>5)
        else
        System.outprintln("fedup with x from school");
        //guess else satament belongs to which if statement??

it's a tricky one isnt it? have a close look and think


Now let break the suspense. java states that else will belongs to closest if that doesnt has else statement. i.e in this else will belong to 2nd if. let's have one more example:

    
    boolean x=false;
    if(x=true)
    {
    
    }
    
    

What's your take on this.


1.Compilation error since '=' is used instead of '=='

,/br>

well you got it wrong!!why?


if any other datatype variable would have been there instead of boolean, it would be surely compiler error.


Here variable x is assign boolean value 'true' and ultimately if expression evaluates too boolean value.


Else if ladder

if you have multiple conditions to check then you can use else if ladder.

let see the foll example to find the maximum of 3 numbers:
class maxi
{
    public static void main(String args[])
    {
    int a,b,c;
    a=Integer.parseInt(args[0]);  //command line argument 
    b=Integer.parseInt(args[1]);
    c=Integer.parseInt(args[2]);
    
    
        if(a>b && a>c)
        {
        System.out.println("a is maximum number");
        }
        else if(b>a && b>c)
        {
          System.out.println("b is maximum number");
        }
        else
        {
          System.out.println("c is maximum number");
        }
    
    }




}

input java maxi 5 2 8


output:c is maximum number


switch statement

switch statement is an replacement for else if ladder, which in case of too many conditions too check,can result into clumpsy and unreadable code.


Syntax:
switch (expression) {
case constant1: code block
case constant2: code block
default: code block
}

A switch's expression must evaluate to a char, byte, short, int, or an enum.


public static void main(String args[])
{

char signal='r';

    switch(signal)
    {

    case 'r': System.out.println("signal is red"); break;
    case 'g': System.out.println("signal is green"); break;
    case 'y': System.out.println("signal is yellow"); break;
    default:System.out.println("technical fault");

    }




}

Output:signal is red


now can you guess the output of next one?
    public static void main(String[] args) {
          
long range=2;

    switch(range)
    {

    case 2: System.out.println("range is 2"); break;
    case 4: System.out.println("range is 4"); break;
    case 6: System.out.println("range is 6"); break;
    default:System.out.println("technical fault");

    }


    }
    


output: compilation fails possible loss of precision


well what's wrong, isnt it like one above.


reason for this is below

A switch's expression must evaluate to a char, byte, short, int, or an enum.

in above e.g long is datatype, hence the problem.


have a look at another one

    byte b = 2;
switch(b) {
case 7:
case 128:
}
    
    
    

output:possible loss of precision


not again, this time its a legal datatype for switch expression.

well the problem lies in the range of byte. 128 is too large for byte.


Now let's go to our 1st example
public static void main(String args[])
{

char signal='r';

    switch(signal)
    {

    case 'r': System.out.println("signal is red"); 
    case 'g': System.out.println("signal is green"); 
    case 'y': System.out.println("signal is yellow"); 
    default:System.out.println("technical fault");

    }




}

output:signal is red


signal is green


signal is yellow


technical fault


got amaze by the output generated just by doing minor change of removing break keyword

this concept is known as fall-through

when the program encounters the keyword break during the execution of a switch statement, execution will immediately move out of the switch block to the next statement after the switch. If break is omitted, the program just keeps executing the remaining case blocks until either a break is found or the switch statement ends.
int dangerlevel = 2;
switch(x) {
case 1: System.out.println("dangerlevel is one");
case 2: System.out.println("dangerlevel is two");
case 3: System.out.println("dangerlevel is three");
break;
case 4: System.out.println("dangerlevel is four");
}
System.out.println("out of the switch");


output: dangerlevel is two dangerlevel is three out of the switch


in this case program as soon as encounter break keyword, it comes out of switch statement


default keyword: if switch expression doesnt match with any case, then default statement is executed.

public static void main(String args[])
{

char signal='n';

    switch(signal)
    {

    case 'r': System.out.println("signal is red"); 
    case 'g': System.out.println("signal is green"); 
    case 'y': System.out.println("signal is yellow"); 
    default:System.out.println("technical fault");

    }




}

output:technical fault


is it necesssary to have default everytime at the end of switch?

your answer is NO. default can come at any places

public static void main(String args[])
{

char signal='n';

    switch(signal)
    {

    case 'r': System.out.println("signal is red"); 
      default:System.out.println("technical fault");
    case 'g': System.out.println("signal is green"); 
    case 'y': System.out.println("signal is yellow"); 
  

    }




}

output:technical fault

signal is green


signal is yellow


fall-through applies even to default cases.


loops and iterations

loops comes in these flavours:


While loop

while loop is used when you dont know the number of times a statement or set of statement should execute.


Syntax

                while(boolean condition)
                {
                
                //if true, execute
                
                }
                

If the boolean expression evaluates to true, then only body of while loop executes.

example:

                int i = 1;
                while(i < 10) {
                System.out.println(i);
                ++i;
                }
                

the above loop will continue to execute until expression result into false, i.e when variable i becomes 10.


Hence output will be:


1
2
3
4
5
6
7
8
9

infinite loop example:

while(true)
{
//loop will run infinitely
}

dowhile loop

dowhile loop is used when you want the body of loop to be executed atleast once, even if condition fails at first attempt.


Syntax

do{


}while(boolean condition);

Note: Be sure to use semicolon(;) at the end of do while loop body.

Example

int i=1;
do{

System.out.println(i);

}while(i <1);

output:

1

even the condition evaluates to false, loops body is executed once.

Have a look at another example.

int i=5;
do{

System.out.println(i);

}while(i=5);

Well, you might think the it is an infinite loop.

Have a close look at boolean expression, it doesnt evaluate to true, instead it is assigning value to variable.

output:compiler error

for loop

for loop is used when you know how many times the block of staement should be executed.


Syntax:

for(initialization;condition;iteration operator)
{
//body of for loop
}

1.initialization will be done only once in the beggining, while conditional and iteration part runs with each iteration.

2.Conditional expression must evaluate to boolean value.

3.After conditional part is evaluated, body of loop is executed before or after iteration part is depended on pre-increment/decrement or post-increment/decrement operator.

lets understand the example:

for(int i=0;i<5;i++)
{
System.out.println(i);
}

1. in the beggining, variable i will be initialize to 0.

2. after initialization conditional part will be evaluated, i.e i<5, condition evaluates to true.

3.now body of loop is executed, and prints value of i as 0.

4.after running the body,iteration part is executed, hence i++, i.e i increment to 1.

5.now conditional part is evaluated again, i.e i<5 i.e 1<5, hence condition evaluates to true.

6.body of loop is executed printing i's value i.e 1

7.again iteration part is run, i increment to 2.

this conditional and iterational part continues to run, until condition turns to false.

output:0 1 2 3 4


What if we skip an part of for loop, like initialization,conditional or iterational,

well, the answer is none is mandatory.

none of the section of for loop is mandatory
for(;;)
{

//we are inside infinite loop
}

the next question arrives in our mind is, can we initialize more than one variable?

can we put more than one conditon?

can we have more than increment operator?

Well the answer is as follow

We can have more than one initialization variable, separated by comma(,)

Conditional part must evaluate to a boolean value, we cannot have 2 conditions with separated comma.

We can have more than one increment variable.

Example:

for(int i=0,int j=0;i<5 || j<2;i++,j++)
{
System.out.println("i:"+i+" j:"+j);
}

lets add one more crucial point.

scope of variable play big role in exam.
for(int i=0;i<5;i++)
{
System.out.println(i);
}
System.out.println("after for loop"+i);

looks like simple 0..4 printing program.

we compiler error, something like variable i undefined at line 4


Enhanced for loop/for each loop

it can be used to iterate through arrays or lists in collection, which we will learn later.

Syntax

for(declaration:expression)
{

}

Declaration section will consist of newly declared variable.

expression part will be the name of array or list you want to iterate through.

int a[]={1,2,3,4};
System.out.println("element in array");
for(int i:a)
{
System.out.println(i);
}

output:1 2 3 4

Explanation:for loop will iterate till the last element in the array a

for each iteration, the value will be temporarily assigned to variable i.

for better understanding try to run the code.

int i;
        int a[]={1,2,3,4};
        for(i:a)
        {
            System.out.println("guess what? you get an error");
        }

output:compiler error:cannot find symbol i

on line 3 for(i:a), i should have been newly declared variable.

Break and Continue

break:it can be used to come out of the loop and also with switch statement.

continue: control is transferred to next iteration.


unlabeled break

Example:

int a[]={1,2,3,4,5}
for(int i=0;i<5;i++)
{

if(i==3)
{
break;
}
System.out.println("element"+a[i]);

}

output:1 2 3

Explanation:

the above code means, that we dont want to print element from 4th position in array.

When i value reaches 3, it satisfies boolean condition and execute break statment.hence program flows goes out of for loop.


as we have already seen break can be used with switch statement also.


unlabeled continue

continue keyword is used to skip the current iteration.

example:

    int a[]={1,2,3,4,5}
for(int i=0;i<5;i++)
{

if(i==3)
{
continue;
}
System.out.println("element"+a[i]);

}
    

output: 1 2 3 5

Explanation:

in this case we want to print the all element of array, except 4th element.

as i becomes 3,if condition get satisfies and continue is executed, which causes program flow to goes to next iteration i,e i=4.

continue can be only used in loops.


labeled break

Control is transferred out of the labeled block of code.

Syntax:

    label labelname:
    for(;;){
        for(;;)
            {
            break labelname;
            }
    }
    
    

label keyword followed by labelname, which must adhere to the rules of valid identifier name.

then calling break statement followed by labelname.

example:


outer:
for(int i=0; i<5; i++)
{
        while (True) {
        System.out.println("Hello");
            break outer;
                        } // end of inner while loop
System.out.println("Outer loop."); // Won't print
} // end of outer for loop
System.out.println("java");
    

output:

Hello

java

explanation:

as in the 1st iteration, execution encounters break outer; statement, flow is transferred outside the loop which is marked as labeled.

in this case labelouter is marked on for loop, hence execution goes to print java


labeled continue

Control is transferred to the iteration part of the labeled block.

Syntax:

    label labelname:
    for(;;){
        for(;;)
            {
            continue labelname;
            }
    }
    
    

label keyword followed by labelname, which must adhere to the rules of valid identifier name.

then calling break statement followed by labelname.

example:


outer:
for (int i=0; i<5; i++) {
for (int j=0; j<5; j++) {
System.out.println("Hello");
continue outer;
} // end of inner loop
System.out.println("outer"); // Never prints
}
System.out.println("java");

output:

Hello

Hello

Hello

Hello

Hello

java

explanation:

as in the 1st iteration, execution encounters continue outer; statement, flow is transferred to the outer loop without executing rest of innerloop .

For each iteration of i, "hello" should have been printed 5 times, but due to labeled continue, it is executed only once per iteration of i.

print statement of "outer" will never be reached.

Inheritance

Inheritance is the mechanism of reusing the code.

It allow reusability of code.


            sry
            
            
            

Inheritance is achieved using extends and implements keywords.

With inheritance, child class get all the members of parents,except those who are marked with private.

Child has the access to the variable var1 and function method1 of parent class as you can see in above diagram.

Child does have access to private member of parent class like var2 and method2().


imagine we have to create program for this scenario.

sry

We 1st create Man class

            class man
            {
            int age;
            public void canTalk(){ System.out.println("talk");}
            public void canWalk(){System.out.println("walk");}
            
            }
            

after creating man class, next step is to create men and women class.

But while creating men and women class, we need to remember, both should have properties of walk and talk.

So should we copy paste the code of Man class, so men and women class will both have the properties?

Problem is we have to repeat the same lines of codes in every class that required the same properties.

this increases code redundancy.

Hence java provide code reusablity by inheritance.

Men and Women class inheriting the Man, would actually inherit all the properties of Man class

code of men class before inheritance is like this.

            class Men
            {
            int male;
            public void menStuff()
            {
            System.out.println("Men stuff");
            
            }
            
            
            }
            
            

inheritance in java is used by extends and implements keywords

implements is used for interface, which will learn later.

after inheritance Men class extends Man class, code look like this

                   class Men extends Man
            {
            int male;
            public void menStuff()
            {
            System.out.println("Men stuff");
            
            }
            
            
            }
            

so what's a change in this code?? only extends Man class!!!

Well!!! implicitly code look like these for JVM

            class Men extends Man
            {
            int age;
            int male;
            public void canTalk(){ System.out.println("talk");}
            public void canWalk(){System.out.println("walk");}
            
            public void menStuff()
            {
            System.out.println("Men stuff");
            
            }
            
            
            
            }
            
            

So as we understood, how extends keywords works, let complete the program for our scenario by making women inherit men.

            class Women extends Man
            {
            int female;
            
            public void femaleStuff()
            {
            System.out.println("female stuff");
            }
            
            
            }
            
            

Understanding IS-A relationship.

child and parent relationship

men and man

women and man

All the above example of inheritance were IS-A relationship.

            class animal
            {
            
            ....
            }
            
            class dog extends animal
            {
            
            .....
            }
            

The above relationship between dog and animal is IS-A relationship

We can say animal is a type of dog.

Understanding Has-a relationship

Has-a relationship is a relationship where one object has reference of another object or object is member of another object.

            class employee{
            address a;
            
            }
            
            class address
            {
            String city,state;
            int pincode;
            
            }
            
            
            

Here Employee object will have the address object as a member variable, hence this is difference between Is-a ans Has-a relationship.

Polymorphism

The word polymorphism means many forms.

1.Method overloading

2.Method overriding

Method overloading

Method overloading is the concept in which there are 2 functions with same name in same scope but different argument or parameter.

Method overloading can be done by:

Different number of argument

Different types of argument

Same number of argument, but different types.

We can change the return type

We can change the access specifier.

            class AreaOfShapes
            {
            
                void area(int length,int breadth)
                {
                System.out.println("Area of rectangle"+(length*breadth));
                }
                
                void area(int side)
                {
                System.out.println("Area of square"+(side*side));
                }
                
                public static void main(String args[])
                {
                AreaOfShapes as=new AreaOfShapes();
                int l=5,b=4;
                int a=4;
                as.area(l,b);
                //call to area of rect
                as.area(a);
                //call to area of square
                }
            
            }
                    
            
            output:Area of rectangle 20
            Area of square:16
            

Which method is invoked depend on matching argument list or argument types

Method overloading in subclass.

We can also overload method in the subclass or child class.

            class Animal
            {
                void move(int legs)
                {
                System.out.println("legs required"+legs);
                }
                
            }
            class Reptiles extends Animal
            {
                void move()
                {
                System.out.println("By crawling");
                }
            
            }
            

Class Reptiles now have 2 move method, 1 with legs argument and other with no-argument.

Method overriding

It is the concept where there are 2 methods with same arguments, same return type, except they are in different scope.1st method is in parent class and 2nd in child class.

In method overriding, which method is getting invoked is determined by the reference type of the object.

Rules for method Overriding

Must have same name

Must have same parameters

same return type except for coveriant type, which will leran later.

The signature of method should be same.

            class A
            {
            
            void getData()
            {
            System.out.println("Class A getdata");
            }
            
            }
            class B extends A
            {
                void getData()
                {
                System.out.println("Class B getdata");
                }
                public static void main(String args[])
                {
                A objecta=new A();
                objecta.getData();
                B objectb=new B();
                objecta=objectb;
                objecta.getData();
                }
            
            }
            
            
            
            Class A getdata
            Class B getdata
            
            

Explanation:

A objecta=new A()

Object of Class A is getting created.

objecta.getData()

As usual, will call getData() of class A

B objectb=new B()

Object of class B is getting created.

objecta=objectb

here object of class A is referencing Class B's object, as parent class object can refer to child class.

objecta.getData()

Since objecta is referring object of class B, and getData() is overrided in class B, function fo class B will be called.

Remember Parent class object on referencing child class, can only call those methods,which are overrided in child class.It cannot call methods specific to child class only.
            class A
            {
            
            void getData()
            {
            System.out.println("Class A getdata");
            }
            
            }
            class B extends A
            {
                void getData()
                {
                System.out.println("Class B getdata");
                }
                
				void doSomething()
				{
					System.out.println("doSomething");
				}
				
                
                public static void main(String args[])
                {
                A objecta=new A();
                objecta.getData();
                B objectb=new B();
                objecta=objectb;
                objecta.getData();
                objecta.doSomething();
                }
            
            }
            
            
            
            output: compiler error
            cannot find symbol objecta.doSomething
            

Access specifier in overriding

The overriding method cannot have more restrictive access specifier than overriden method.

If you marked method public in parent class then you cannot mark the overriding method as private.

             class A
            {
            
            public void getData()
            {
            System.out.println("Class A getdata");
            }
            
            }
            class B extends A
            {
               private void getData()
                {
                System.out.println("Class B getdata");
                }
                public static void main(String args[])
                {
                A objecta=new A();
                objecta.getData();
                B objectb=new B();
                objecta=objectb;
                objecta.getData();
                
                }
            
            }
            
           
            
            
            
            output:Compiler error
            getData() in B,cannot override getData() in A
            Attempt to assign weaker priviledges.
            

So, beware of access type in method overriding.

Coveriant return type

Before java5,Return type of overriding method should be same,but since in java 5 Coveriant return type was introduced.

if overriden method is returning its own object i.e parent class object as return type, then overriding method can return its own object i.e child class object as return type.

             class A
            {
            
            public A getData()
            {
            System.out.println("Class A getdata");
            }
            
            }
            class B extends A
            {
               private B getData()
                {
                System.out.println("Class B getdata");
                }
                
            
            }
            
            

Even though, getData() in class A has return type of A, the overriding method in class B has return type of B, this concept is known as Coveriant return type.

Remember, you cannot override method which are marked static, since static members dont belong to objects.
You cannot override method which cannot be inherited, i.e private method.

Reference variable casting

Converting a class type into another type is acheived by casting,but there should be relationship between them through inheritance.

When Parent class refer to child class, it is known as down-casting.This is also called Specialization.

When Child class refer to Parent class, it is known as up-casting.This is also called Generalization.

Generalization

Generalization is safe,because child will inherit all the properties that parent have.

            Parent p=new Parent();
            Child c=new Child();
            p=c;
            //implicity compiler does this 
            //p=(Parent)c;
            
            
Specialization

specialization is unsafe,we need to do explicit casting.

            Animal a=new Animal();
            Dog d=new Dog();
            d=(dog)a;
            
            
When Child object refer to parent object, we need explicit casting. but vice versa is not needed.
Exam catch
            Parent p=new child();
            ((child)p).getData();
            
The above code is equivalent to somethin like this.
            Parent p=new Child();
            Child c=(Child)p
            c.getData();
            
            

Interface

Java does not allow to extends from more than 1 class. Hence we cannot extends from more than one class.

            class A extends B,C    //illegal
            

But we can implements more than 1 interface.

Interface specifies a contract that whichever subclass that implements it, has responbility of providing implementation for the method declared in interface.

Rules for interface

All methods in interface are implicitly public and abstract.

interface method must not be static,final,strictfp,native.

All variables declared in an interface are public,final and static.

when implementing the method of interface, the method of subclass should have access specifier public.

            interface A
            {
            int age;
            String name;
            
            void getData();
            }
            
            

implicitly code look like this

            interface A
            {
            public static final int age;
            public static final String name;
            
            public abstract void getData();
            }
            

When a subclass implements interface, it is responsibility of subclass to provide body defination of method declared in interface and also defination should have public access specifier.

            class B implements A
            {
            
                public void getData()  
                {
                System.out.println("Hi");
                
                }
            
            }
            

Important to know

interface cannot implements other interface

interface can extends 1 or more interface

A classcannot extends interface

interface cannot extends class

            interface A
            {
            void getData();
            }
            
            interface B implements A  //this is illegal,interface cannot implements other interface
            
            interface B extends A //legal,interface can extends other interface
            
            class C extends A  //illegal, class cannot extends interface
            {
            
            }
            
            
            interface B extends C   //illegal interface cannot extends class
            
            
We cannot create object of inteerface but we can create reference variable of it.

Constructor

When the object is created, constructor is first invoked.

Constructor is the special method that doesnt have return type, but same name as class.

            class Ant
            {
                Ant()
                {
                System.out.println("constructor invoked, object created");
                
                }
            public static void main(String args[])
            {
            Ant a=new Ant();
            }
            
            }
            
            
            output:constructor invoked,object created

Constructor is the first thing that get invokes on object creation.

Every class should have default constructor, but it doesnt mean that programmer should write a constructor. If a class doesnt have constructor, then compiler will create default constructor for the class.

            class Ant
            {
            
            
            }
            

But when you compile, compiler will put default constructor for you.

            class Ant
            {
                Ant()   //default constructor added by compiler.
                {
                
                }
            
            
            }
            

Constructor with parameter

We can have the constructor with paramaters, this is known as constructor overloading.

We can have more than 1 constructor in a class.

A constructor without any argument is known as default constructor.

            class Ant
            {
            
                public Ant()
                {
                System.out.println("default constructor");
                }
            
                public Ant(int num)
                {
                System.out.println("Number of Ants"+num);
                }
                
                public Ant(int num,String color)
                {
                  System.out.println("Number of Ants"+num+" and color of ants "+color);
                }
                
                public static void main(Stringargs[])
                {
                Ant a=new Ant();
                Ant a2=new Ant(2);
                Ant a3=new Ant(3,"black");
                }
            
            }
            
            
            output:
            default constructor
            Number of Ants 2
            Number of Ants 3 and color of ants black
            
            

Explanation:

1st object a invoked default constructor.

2nd object a2 as per the argument called the matching 2nd constructor

2nd object a3 as per the argument called the matching 3rd constructor


Call to Super constructor

Every constructor invokes the default constructor of superclass, before getting executing itself.

             class animal
             {
             animal()
             {
             System.out.println("Animal constructor invoked");
             }
             
             }
            class Ant extends animal
            {
                Ant()
                {
                  //super(); added by compiler, which result into call for parent class constructor
                System.out.println("Ant constructor invoked, object created");
                
                }
            public static void main(String args[])
            {
            Ant a=new Ant();
            }
            
            }
            
            
            Output:
            Animal constructor invoked
            Ant constructor invoked, object created
            
            

Explanation:

Ant a=new Ant()

On above line, Ant class object is created, which result into invokation of its constructor.

On first line of Ant constructor, compiler adds super(), which result into call of its parent class constructor.

Hence animal class constuctor get invoked which invokes Object class constructor and after execution control pass back to Ant class constructor.

Super and this in constructor

An constructors 1st line should be mandatory super() or this().

If you have not written super keyword then compiler will add super() to the constructor's 1st line.

While super is used for calling parent class constructor, this keyword can be used for calling same class constructor

Since every class extends from Object class in java, everytime an object is created, call is made to Object class constructor.Even though we dont write that class extends Object class, but it exist.

        class Person
            {
                Person()
                {
                  System.out.println("Default in Person");
                }
            
            }
            class Employee extends Person
            {
                Employee()
                {
                 System.out.println("Default in Employee");
                }
                Employee(int num)
                {
                this();
                 System.out.println("parameterized in Employee");
                }
            }
            class Manager extends Employee
            {
                Manager(int num)
                {
					
                super(num);
                System.out.println("Default in Manager");
                }
                
                public static void main(String args[])
                {
					int num=2;
                Manager m=new Manager(num);
                }
            }
            
            Default in Person
            Default in Employee
            parameterized in Employee
            Default in Manager
            

Explanation:

On creating object of Manager class with parameter, call goes to parameterized constructor of Manager.

Since Super keyword is uesd, call goes to parent class Employee's parameterized constructor. In which this keyword is used, so call goes to Employee default constructor. Since first Statement should be either super or this in constructor, in this case both are missing, so compiler adds the super keyword, which result into call of Person default constructor.

Hence "Default in Employee" gets printed first, then call return back to the constructor which has called it, i.e Employee default constructor and prints "Default in Employee" and so on in the order they were called.


No default constructor added if paramaterized constructor exist.

If parameterized constructor exist but default doesnt exist then, compiler wont add default constructor to your code.

            class animal
            {
            
            animal(int num)
            {
            System.out.println("parameterized constructor");
            }
            
            public static void main(String args[])
            {
            animal a=new animal();
            
            }
            
            }
            
            

guess what is the output?

            output:Compiler error
            animal.java:11: error: constructor animal in class animal cannot be applied t
o given types;
            animal a=new animal();
                      ^
  required: int
  found: no arguments
  reason: actual and formal argument lists differ in length
1 error
            

Explanation:

Compiler will only add default constructor if there no constructor exist for class,Hence when object is created with no argument, it fails to find constructor with no argument.

            class Animal {
Animal(String name) { }
}
class Horse extends Animal {
Horse() {
super(); // Problem!
}
}
            
            
            Compiler error:cannot resolve symbol super();
            

There should be match for constructor with appropriate arguments.

Rules for constructor

Constructor can have any access specifier, if it is private, then it means object can be only created within the class.

Constructor must have same name as class name.

It should have return type, if it does, then its not constructor but it an method.

If you dont have constructor in class, then default constructor will be added by compiler.

If you have any other constructor, then compiler wont provide default constructor.

First statement in constructor should be either super or this statement, bydefault compiler will add super() to your constructor.

you cannot access instance variable or method inside constructor.only static variable can be accessed.

Abstract classes can have constructor, they are called when concrete subclass object is created.

Interface do not have constructor.

You cannot call constructor explicitly, it is called only on object creation.

Coupling and Cohesion

Ideally there should loose coupling and tight cohesion. Coupling: it is the degree to which one class knows about others.If an other class only know what is expose through interface, then it is loosely coupled.
Example of tight coupling
            class address
            {
            public String street,city,zip;
            
            }
            
            
            class employee
            {
            public address home;
            
            employee(String street,String city,String zip)
            {
            home.street=street;
            home.city=city;
            home.zip=zip;
            }
            
           
            
            
            
            }
            
let see example of loose coupling
            class address
            {
            private String street,city,zip;
            
             //all setters
            public void setStreet(String s)
            {
            street=s;
            }
            
             public void setCity(String c)
            {
            city=s;
            }
            
             public void setZip(String z)
            {
            zip=z;
            }
            
            }
            
            
            class employee
            {
            private address home;
            
            employee(String street,String city,String zip)
            {
            home=new address();
            home.setStreet(street);
           home.setCity(city);
           home.setZip(zip);
            }
            
            
            }
            
CohesionIt is the degree to which an class has well defined,single purpose.High cohesion is when an object performs multiple task that are not related to each other. Low cohesion is when an object performs multiple tasks that are not related to each other. Classes that implements high cohesion are more reusable and easier to test and understand.
For e.g in case of ATM, withdraw class should only do withdraw operation and should not do any inquiry or deposit operation.
Highly cohesive classes are easily maintanable and re-usable.

Wrapper Classes

Java is object oriented, but it is not pure object oriented due to primitive datatypes.

To convert this primitive datatype into Objects, we have Wrapper classes.

There is Wrapper class for each primitive datatype.

Wrapper class have the first letter capital with respect to datatype, except for char datatype.

sry
    			
Note that except Character wrapper class,every other classes constructor has 2 argument, 1 for primitive and other for String.Character constructor can take only char as argument.

Examples of constructing wrapper object.

                Integer i=new Integer(5);
                or
                Integer i=new Integer("5");
                same syntax follows for other wrappers except char which has 1 syntax.
                Character c=new Character('a');
                

Methods of wrapper class

valueOf() and xxxValue() are two most important methods of wrapper class. which are likely to come in exam.

in xxxValue() xxx refer to respective datatype name.


valueOf()

It returns the object of primitive datatype.

It has 2 syntax.

1. take String representative as argument.

2. take String representative as a 1st argument, and 2nd argument specify in which base it is represented.

                Integer i1=Integer.valueOf("5"); //return Integer object and assign value 5 to it.
                Integer i2=Integer.valueOf("101",2); //indicate argument is in binary base and then convert it into decimal i.e 5 and return integer object.
                Long l=Long.valueOf("35");
                

Now as we know, how to convert primitive to Object using valueOf() or constructor.

We should know, how to convert Wrapper object to primitive .

xxxValue()

xxx refers to respective datatype.

WrapperClass method

Integer intValue()

Float floatValue()

Long longValue()

Short shortValue()

Double doubleValue()

Byte byteValue()

Character charValue()

                
                Integer i1=new Integer(5);
                int i=i1.intValue();
                short s=i1.shortValue();
                long l=i1.longValue();
                byte b=i1.byteValue();
                
                
                

parseXXX()

it returns primitive value of the String argument passed to it.

                int i=Integer.parseInt("5");
                similar for other wrappers too
                float f=Float.parseFloat("35.02f");
                Long l=Long.parseLong("35");
                double d=Double.parseDouble("35.02");
                

toString()

it gives the primitive value in the form of String.

                Double d=new Double("78.05");
                String ds=d.toString();
                same syntax for other wrappers too
                

toBinaryString(),toHexString(),toOctalString()

Convert number in 10 base to other base and return in String format.

                String binFormat=Integer.toBinaryString(5);
                String octFormat=Integer.toOctalString(5);
                String hexFormat=Integer.toHexString(10);
                

if you print it output will be:

101

5

a

Important Note to remember.

xxxValue(): to convert a Wrapper to a primitive

valueOf():to convert a String to a Wrapper

parseXXX():to convert a String to a primitive

Autoboxing

AutoBoxing is the new feature introduced in java 5.

Before java 5

            Integer i=new Integer(10);
            if(i>5);  //produces error
            {
            
            }
            
            
            

Output:compiler error

so to make it compile we have to do something like this.

            Integer i1=new Integer(10);
            int i2=i1.intValue();  //unboxing
            if(i2>5);  //result into true
            {
            i2++;
            i1=new Integer(i2);   //boxing
            }
            
            System.out.println("incremented value of wrapper object "+i1);
            

output:11

Did you so much things to do for just incrementing wrapper object!!!

We had to unbox i1 by using intValue()

then we had too increment int primitive and box it again to wrapper object.


Now let see same example with java 5 autoboxing featute

            
            Integer i=new Integer(10);
            if(i>5)
            {
            i++;
            System.out.println("autoboxing"+i);
            }
            

output:11

With autoboxing feature, at line 2, i is unboxed and then its primitive is compared to value 5.

then at line4, i is again unboxed, it primitive is incremented and again boxed.

Method overloading with autoboxing,widening,var-args

method overloading Widening

            class Widening {

        public static void main(String [] args)
        {
        byte b = 10;
        float f = 10.0f;
        getCall(b);
        getCall(f);
        }
        
        static void getCall(int x) { System.out.print("int "); }
        static void getCall(double x) { System.out.print("double "); }
        
        
                            }
            
            

output:int double

As you see, when exact match is not found,it tries to find the nearest match.

Since byte and short are implicitly convertible to int, getCall() with int argument is called.

In case of float, nearest match is double, so its widen to match getCall with double argument.


Widening with Reference variable.

            class Sample
            {
            
            }
            class WideningRef extends Sample
            {


                public static void main(String [] args) {
                WideningRef wr=new WideningRef();
                
                getCall(wr); 
                }
                
                static void getCall(Sample s) { System.out.println("Widening Ref"); }
            }
            
            
            output:Widening Ref
            

WideningRef extends Sample class, so it means WideningRef inherit the properties of Sample class

Hence WideningRef can do what Sample class can do.so compiler widens wr to match the method that take Sample as argument.

Widening with Wrapper class

              class WideningWrapper 
            {


                public static void main(String [] args) {
                Integer i =new Integer(5);
                getCall(i); 
                }
                
                static void getCall(Long x) { System.out.println("Wrapper widening"); }
            }
            
            output:Compiler error inconvertible types from Ibnteger to Long.
            

Wrapper class are individual classes and dont have any inheritance relation with each other, hence Wrapper object dont widen.


Method overloading with autoboxing

            class Boxing 
            {


                public static void main(String [] args) {
                int i = 5;
                getCall(i); 
                }
                
                static void getCall(Integer x) { System.out.println("Integer"); }
            }
            
            

output:Integer

In this case, when exact match is not found,parameter does autoboxing to find the nearest match.


Method overloading with var-args

            class varargloading 
            {


                public static void main(String [] args) {
                int i = 5;
                int j=6;
                getCall(i,j); 
                }
                
                static void getCall(int... x) { System.out.println("var-args"); }
            }
            
            

output:var-args

Method overloading with widening,var-args

            class VarargsCheck 
            {

                public static void main(String[] args) {
                byte b = 5;
                getCall(b,b); // which getCall() will be invoked?
                }
                
                static void getCall(int x, int y) { System.out.println("int,int");}
                static void getCall(byte... x) { System.out.println("byte... "); }
            }
            
            output:int int
            

Compiler chooses widening over var-args

Reason:Var-args is the new addition to the java features, hence to keep the old code still working, compiler chooses widening over var-args


Method overloading with widening,boxing

            class VarargsCheck 
            {

                public static void main(String[] args) {
                byte b = 5;
                getCall(b,b); // which getCall() will be invoked?
                }
                
                static void getCall(int x, int y) { System.out.println("wideing int");}
                static void getCall(Byte x,Byte y) { System.out.println("Boxing int "); }
            }
            
            output:widening int
            
Remember: Widening beats var-args and Widening beats boxing in method overloading.

Method overloading with Boxing,var-args

            class AddVarargs {
                               
                                public static void main(String[] args) {
                                byte b = 5;
                                getCall(b,b); // which getCall() will be invoked?
                                }
                                
                                 static void getCall(int x, int y) { System.out.println("Boxing wins");}
                                static void getCall(byte... x) { System.out.println("Var-args wins "); }
                             }
            
            
            output:Boxing wins
            

So, what you learn from it!

Remember: Var-args is always a loser, i.e always last preferred option in method overloading.

Method Overloading with all combination

             class Sample {
                               
                                public static void main(String[] args) {
                                byte b = 5;
                                getCall(b,b); // which getCall() will be invoked?
                                
                                }
                                
                                 static void getCall(Byte... x) { System.out.println("Boxing and Var-args");}
                                 
                                static void getCall(Integer... x) { System.out.println("Widen and Box "); }
                             }
            
            
            
            output:Boxing and Var-args
            
Remember: You can never Widen and then Box

Rest all combination works like:

Box and Widen

Vararg and widen,Var-args and box

Box and Widening

            
            class Sample {
                               
                                public static void main(String[] args) {
                                byte b = 5;
                                getCall(b,b); // which getCall() will be invoked?
                                
                                }
                                
                                 static void getCall(Byte... x) { System.out.println("Boxing and Var-args");}
                                 
                                static void getCall(Object... x) { System.out.println("Boxing and widen "); }
                             }
            
            
            output:Compiler error Reference to getCall is ambiguous
            
            

since both Boxing and var-args is valid and Boxing and Widening

Garbage Collection

Garbage collection: it is the process of removing the object from memory, which are no longer needed.

It is memory management technique.

So when does object becomes elligible for garbage collection.

            class Sample
            {
            
                public static void main(String args[])
                {
                Sample s=new Sample();    //Object allocated memory 
                s=null;       //object becomes elligible for garbage collection
                }
            
            
            }
            
            
            

When Object is refernced to null, it becomes elligible for garbage collection.

let see another case elligible for garbage collection.

              class Sample
            {
            
                public static void main(String args[])
                {
                Sample s=new Sample();    //Object allocated memory 
                s.getCall()      
                }
            
                public void getCall()
                {
                Sample s2=new Sample();   
                }
            }
            
            
            

Sample class object s2 becomes elligible for garbage collection after execution of getCall method,since its scope is in within method.

hence object declared inside method becomes elligible for garbage collectio unless the object created is return back.

What do i mean by previous statement?? let check the code.

            class Sample
            {
            
                public static void main(String args[])
                {
                Sample s=getCall();    
                  
                }
            
                public static Sample getCall()
                {
                Sample s2=new Sample();   
                return s2;    //here S2 is not elligible for garbage collection
                }
            }
            
            
            

in the above case, the object created in method will be referred by another referenced variable, hence S2 will not be elligible for garbage collection.


System.gc()

this method is available for requesting JVM for performing garbage collection.

Although it deosnt guarantee that JVM will do garbage collection after this function.

finalize()

if you want to some clean up code when object is getting deleted, you can write that in finalize()

finalize() runs before object is destroyed.

Exception Handling

Exception:Exception is defined as a abnormal condition that alters the flow of program.

Java uses try-catch mechanism to handle exception.

Keywords that are important in Exception handling

KeywordsDescription
tryCode that is likely prone to error are contained within try-block.if exception is thrown within try block,exception is thrown.
catchException thrown by try-block is handled in catch block
throwTo throw user defined exception or manually throw the exception.
throwsTo indicate that exception will not be handled by called method and it should handled by calling method.
finallyAny code that must run, whether exception occrus or not.

Types of Exception

             sry
           
             

Throwable is the subclass of Object class. Exception and Error classes are the subclasses of the Throwable class.Exception class is the superclass of all exception classes.

Subclasses under Exception class

RuntimeException:Thrown when the arithmetic operations performed in programs are incorrect


IOException:Thrown when the IO(Input and Output) operations has failed


InterruptedException:Thrown when the thread is sleeping or waiting.


IllegalAccessException:Thrown when the method is called in another method, however the method does not have permission to access that method.


Subclasses under RuntimeException

ArithmeticException


ArithmeticException


ArrayIndexOutOfBoundException


IllegalArgumentException


ArrayStoreException


NegativeArraySizeException


NullPointerException


NumberFormatException


Checked Exception

They are Exception that are determined at Compile time by compiler. Checked Exception should be either handled by programmer or throw them.

ExceptionDescription
IOExceptionError in performing IO operation
ClassNotFoundExceptionClass not found
InterruptedExceptionone thread has been interrupted by another thread
IllegalAccessExceptionAccess to class is denied
Unchecked Exception
ExceptionDescription
ArithmeticExceptionArithmetic Error,such as divide by zero
ArrayIndexOutOfBoundExceptionArray index is out of bound
ArrayStoreExceptionAssignment to an array element of an incompatible type
IllegalArgumentExceptionIllegal argument used to invoke a method
NegativeArraySizeExceptionArray created with a negative size
NullPointerExceptioninvalid use of null reference
NumberFormatExceptionInvalid conversion of a string to a numeric format

They are Exception that are determined at Runtime by compiler.

Multiple catch

Try block is used to define the piece of code where exception can occur.

Catch block is used to handle the exception, it must be written immediately after try block. one try statement can have multiple catch blocks.

Syntax

             try
             {
                  //lines of codes that can cause exception
             }
             catch(Exception e)
             {
                //handling exception.
             }
             catch(Exception e2)
             {
             
             }
             
             
             
             class SampleClass
             {
             int a=10,b=0,answer;
             public void getData()
             {
             
             
                try{
                    answer=a/b;
                    }
                    catch(ArithmeticException e)
                    {
                     System.out.println("Arithmetic exception divide by zero");
                    }
                    catch(Exception e){
                    System.out.println(" exception  ");
                    }
             }
             
             public static void main(String args[])
             {
             SampleClass sc=new SampleClass();
             sc.getData();
             }
             
             }
             
             
             output:
             Arithmetic exception divide by zero
             

As we can see, we can have more than catch block for single try statement, but these catch block should be hierarchy from more specific to general. i.e ArithmeticException is more specific exception class,Exception is more general class.

             class SampleClass
             {
             int a=10,b=0,answer;
             public void getData()
             {
             
             
                try{
                    answer=a/b;
                    }
                    catch(Exception e)
                    {
                     System.out.println("Arithmetic exception divide by zero");
                    }
                    catch(ArithmeticException e){
                    System.out.println(" exception  ");
                    }
             }
             
             public static void main(String args[])
             {
             SampleClass sc=new SampleClass();
             sc.getData();
             }
             
             }
             
             
output
             Compiler error
             exception ArithmeticException has already been caught.
             

Compiler error is thrown if the order of exception is not proper in catch block. Order should be from more specific to general form. Since Exception is parent class, its subclasses should come before itself in catch block.

Nested try catch

It is legal to have try-catch block inside another try block.

      class SampleException
             {
             
                public void doSomething()
                {
                int result=0;
                    try{
                    
                            try{
                            result=5/0;
                            
                            }catch(ArithmeticException e)
                            {
                                System.out.println("Divide by zero error");
                            }
                            
                    int c=Integer.parseInt("54fgf");
                    
                    }
                    catch(NumberFormatException ex)
                    {
                            System.out.println("NumberFormat Exception" );
							
                    }
                
                
                
                }
				
				public static void main(String args[])
				{
					SampleException se=new SampleException();
					se.doSomething();
				}
             
             }
             
output
             Divide by zero error
             Numberformat Exception
             
             
             

As we can see, we caught different exception in inner try block and other in outer try block.

Finally

A Finally block includes codes that is always executed whether exception occurs or not.Even if htere is the return statement in try block, finally will still run.

If the try block executes with no exceptions, the finally block is executed immediately after the try block completes. If there was an exception thrown, the finally block executes immediately after the proper catch block completes

Syntax:

             try
             {
             
             }
             catch(Exception e)
             {
             
             }
             finally
             {
             // code that will always run after try, generally releasing of resources are done here.
             }
             
             

If the try block execute normally then, Finally will run immediately after it or if the exception occurs in try, then matching catch block gets executed then finally runs.

Finally immediately after Try

Sometimes, we can see the code snippets where, finally block is immediately followed after try block without catch block.

Syntax.

             try
             {
             //code likely to cause ecxeption
             }
             finally
             {
             //cleaning of resources
             }
             
             
try statement must either followed by catch or finally. but cannot be single alone. Its illegal to have any code between try-catch and finally block

Exception propagaton

in java call stack is maintained, if main() call A(), then A() calls B() and further B() calls C() then callstack look something like this.

             C
             B
             A
             main
             
             

As we see the method at the top of stack is currently executing and as we move downward, the method appears in the way they were recently called.


So what does have call stack has to do with Exception?

Answer: Well it does matter. Exception is propagated in the order of callstack. Suppose if Exception is thrown by method C() and it is not handle by it, then exception is propagated to method B(). After B(), the exception is propagated to A() and then to main method which will eventually handled by JVM.

Bydefault Unchecked Exception are propagated in call stack. Checked Exception are not propagated.
...more coming soon

throws keyword

throws keyword is used to declare what exception an method can throw.

Every method that can throw exception, must declare the exception.

Checked exception must either declared or handle by catch block. Unchecked exception do not have to be specified or handled.

Syntax

             void doSomething() throws Exception
             {
             
             //code that might throw exception
             
             }
             
             
             class throwsException
{
	public void doSomething() throws ArithmeticException
	{
	throw new ArithmeticException();
	}
	
	public void handleSomething()
	{
		try{
		doSomething();
		}
		catch(ArithmeticException ae)
		{
		System.out.println("Exception handled in handleSomething method");
		}
	
	}
	
	
	public static void main(String args[])
	{
	throwsException te=new throwsException();
	te.handleSomething();
	}


}
             
             
output
             Exception handled in handleSomething method
             
             

we can see that doSomething() doesnt handle exception but declare it, while handleSomething doesnt declare but handles the exception. Hence for checked exception, we should either handle or declare.

If the exception is thrown in catch block itself then it must be declared by method or error will be declare by compiler.

Custom Exception

We can create custom exception in java, by extending Exception class.

Syntax

             class MyException extends Exception
             {
                MyException()
                {
                System.out.println("MyException");
                }
             
             
             }
             
             

lets create an custom exception, if age is below 18 years

             import java.util.*;
import java.io.*;
class AgeException extends Exception
{
	public AgeException()
	{
	System.out.println("Age is below 18");
	}


}

public class CustomException 
{

	public static void main (String args[])
	{
	int age;
	Scanner sc=new Scanner(System.in);
	System.out.println("Enter your age ");
	age=sc.nextInt();
	
	try
	{
		if(age<18)
		{
			throw new AgeException();
		}
	}
	catch(AgeException ae)
	{
	System.out.println("Custom Exception is generated ");
	}
	
	}



}
             
             

output

             Enter your age
             15
             Age is below 18
             Custom Exception is generated
             
             

Assertion

Asseertion was added to java in 1.4 version.So before 1.4 assert can be used as identifier.Assertion let you test your assumption.If you want to validate or test your assumption during debugging, without making a print statement then assertion comes to your help.It leaves no overhead or debugging code to trackdown and remove.


Assertion are inactive unless enabled at runtime.


There are 2 forms of Assertion.


1.Simple


2.Really Simple

Difference in two version is that Simple version adds a string value to the stack trace,while Really Simple only states that assumption was false.

Really Simple

Syntax

             assert(condition);
             
             
             

Assertion always makes conditon evaluates to true, if it doesnt then it throws AssertionError.

         class SampleAssertion
             {
             
             public void  doSomething(int age)
             {
                assert(age>18);
                System.out.println("You are adult");
             
             }
             
             
                public static void main(String args[])
                {
                SampleAssertion sa=new SampleAssertion();
                sa.doSomething(5);
                }
             
             }
             

output

             Exception in thread "main" java.lang.AssertionError
             
             

As ReallySimple assertion puts AssertionError as soon as the assumption becomes false.

Simple

Simple Assertion adds a string value to stacktrace to give more idea about error.

Syntax

             assert(boolean condition):"String value";
             
             
         class SampleAssertion
             {
             
             public void  doSomething(int age)
             {
                assert(age>18):"age is less than 18";
                System.out.println("You are adult");
             
             }
             
             
                public static void main(String args[])
                {
                SampleAssertion sa=new SampleAssertion();
                sa.doSomething(5);
                }
             
             }
             

output

              Exception in thread "main" java.lang.AssertionError: age is less than 18
             

Enabling of Assertion

Assertion are disabled by default.But they can be turned on whenever needed.

Assertion can be enabled at runtime with:

             java -ea classname
             
             or 
             
             java -enableassertion classname
             
             

Disabling of Assertion at runtime

             java -da classname
             
             or 
             
             java -disableassertion classname
             
             
             

String

String are immutable object

What do you means by String is immutable in java?

Immutable means once created, it cannot be changed.

    class Immutable
        {
            public static void main(String args[])
            {
            String name="hello ";
            System.out.println("before concat "+name);
            name.concat("earnjava");
            System.out.println("after concat "+name);
            
            
            
            }
        
        
        }
        

Output

                before concat hello
                after concat hello
                
                
sry

    			

As we saw "earnjava" did not got appended to String variable name in above example, but infact 2 String object got created. 1st object with literal "hello " and 2nd object with literal "hello earnjava". but reference to 2nd object is lost and no one is pointing towards it.

    class Immutable
        {
            public static void main(String args[])
            {
            String name="hello ";
            System.out.println("before concat "+name);
            name=name.concat("earnjava");
            System.out.println("after concat "+name);
            
            
            
            }
        
        
        }
        

Output

                before concat hello
                after concat hello earnjava
                
                
sry

    			

In the above example 2nd String object formed "hello earnjava" is referenced by String name and reference to 1st object "hello" is lost.

Creating String

In java String can be created with literals or with new keyword.

                class StringCreation
                {
                
                    public static void main(String args[])
                    {
                    String s1="abcd";
                    String s2=new String("abcd");
                    String s3="abcd";
                    String s4=new String("abcd");
                    
                    
                    if(s1==s2)
                    {
                    System.out.println("s1==s2");
                    }
                    if(s1==s3)
                    {
                    System.out.println("s1==s3");
                    }
                    if(s2==s4)
                    {
                    System.out.println("s2==s4");
                    }
                    
                    
                    
                    }
                
                }
                

output

                s1==s3
                

output is s1==s3, because s1 and s3 are String not created with new keyword,and they are formed in String pool, while s2 and s4 are created with new keyword, hence they are not formed in String pool and separate memory is allocated to them. "==" operator check for the reference. Since s2 and s4 are formed with new keyword, they have different memory location, hence s2 is not equal to s4 even though their value is same. s1 and s3 are String literals, hence they are formed in String pool and refer to same object.

sry

    			
Important methods of String class
method meaning
charAtReturn the character at specified index
concatappend one string to the end of another
lengthreturn the number of character in string
replaceReplace occurences of character with a new character
substringreturn a part of string
toLowerCasereturn a string with lowercase converted
toStringreturn the value of string
toUpperCasereturn the value of string converted in uppercase
trimremoves the whitespace from string

StringBuffer and StringBuilder

String is immutable,hence a lots of String object are created which later loses their reference and never used.In the scenario where we have to do lot of modification to string such as during I/O programs. In this case we have StringBuilder and StringBuffer classes for help.

Difference between StringBuffer and StringBuilder

StringBuffer StringBuilder
StringBuffer is SynchronizedStringBuilder is not Synchronized
StringBuffer is thread safeStringBuilder is not thread safe
StringBuffer is slowStringBuilder is faster
StringBuffer is less efficientStringBuilder is more efficient

let see the same String concatenation through StringBuilder.

                class SBuilder
                {
                
                    public static void main(String args[])
                    {
                    StringBuilder sb=new StringBuilder("hello ");
                    System.out.println("before appending "+sb);
                    sb.append("earnjava");
                    System.out.println("after appending"+sb);
                    
                    
                    }
                
                
                }
                
                
                

output

                before appending hello
                after appending hello earnjava
                
                

So we could see that StringBuilder is mutable, unlikely String class.

Methods in StringBuffer and StringBuilder
method meaning
append(String s)It can be used to attached the specified string to the existing string.It can take other arguments like char,int,float,double etc.
insert(int offset,String s)Used to insert specified String in the existing StringBuffer/StringBuilder object at specified offset.
replace(int startIndex,int endIndex,String str)Replace the existing String with specified String from startIndex to EndIndex.
reverse()It simply reverses the StringBuilder/StringBuffer object.
substringreturn a part of string
public int capacity()current capacity of existing object.
public String toString()return the value as a String
public String substring(int beginIndex)return the value of string from specified index.
public String substring(int beginIndex,int endIndex)return the String from beginIndex to EndIndex.

InnerClass

A class declared inside other class is known as inner class. Yes you heard it right!!! class is enclosed inside curly braces of another class.

Various types of innerclass are:

  • Member inner class
  • local method inner class
  • Anonymous inner class
  • Static nested class

Member Inner Class

It is a class defined inside another class.

                
           class SampleInnerClassA
                {
                String name="Hello";
                    class SampleInnerClassB
                    {
                        void accessing()
                        {
                        System.out.println("Accessing outerclass data "+name);
                        }
                    }
                    
                    public static void main(String args[])
                    {
                    SampleInnerClassA ca=new SampleInnerClassA();
                    SampleInnerClassA.SampleInnerClassB cb=ca.new SampleInnerClassB();
                    cb.accessing();
                    
                    }
                
                }
                

output

                Accessing outerclass data Hello
                

To create instance of innerclass, we need an instance of outerclass, but if we are creating innerclass instance from outerclass instance member method then we'll do it this way.

                 class SampleInnerClassC
                {
                String name="Hello";
				
				void creator()
				{
					
					SampleInnerClassD cd=new SampleInnerClassD();
					cd.accessing();
					
				}
				
				
                    class SampleInnerClassD
                    {
                        void accessing()
                        {
                        System.out.println("Accessing outerclass data "+name);
                        }
                    }
                    
                    public static void main(String args[])
                    {
                    SampleInnerClassC cc=new SampleInnerClassC();
                  //  SampleInnerClassA.SampleInnerClassB cb=ca.new SampleInnerClassB();
                    cc.creator();
                    
                    }
                
                }
                
                

output

                Accessing outerclass data Hello
                
                

In creator() method we already have reference to outerclass as this will be pointing implicitly. Hence to create inner class instance we just need to create is object.

Following modifier can be applied to inner class: public protected,private,final,abstract,static,strictfp.

Method local innerclass

A class created within the method is known as Method local innerclass.

                   public class Outer
                    {  
                         
                         void data(){  
                                        class Inner{  
                                        void innerData(){System.out.println("Hi in Innerclass");}  
                                                    }  
                          Inner l=new Inner();  
                          l.innerData();  
                                        }  
                         public static void main(String args[]){  
                          Outer obj=new Outer();  
                          obj.data();  
                         }  
                    }  
                

Output

                Hi in Innerclass
                

Local innerclass can't access the local variables of method.

                   public class Outer
                    {  
                         
                         void data(){  
                         int myNumber=10;
                                        class Inner{  
                                        void innerData(){System.out.println("Hi in Innerclass :"+myNumber);}  
                                                    }  
                          Inner l=new Inner();  
                          l.innerData();  
                                        }  
                         public static void main(String args[]){  
                          Outer obj=new Outer();  
                          obj.data();  
                         }  
                    }  
                

Output

                error:local variable myNumber is accessed within innerclass;need to be declared final
                

Hence to access to local variables of method, we need to declare them final.

                   public class Outer
                    {  
                         
                         void data(){  
                         final int myNumber=10;
                                        class Inner{  
                                        void innerData(){System.out.println("Hi in Innerclass :"+myNumber);}  
                                                    }  
                          Inner l=new Inner();  
                          l.innerData();  
                                        }  
                         public static void main(String args[]){  
                          Outer obj=new Outer();  
                          obj.data();  
                         }  
                    }  
                

Output

                Hi in Innerclass :10
                
Note:From java 1.8 we can access local variable from innerclass.

Anonymous inner class

It is a class without class name.When you see the object of class is created alongwith the body, then it as anonymous class.
Anonymous class is actually subclass.

               class Rock
                {

                    public void color()
                    {
                        System.out.println("Color is gray");
                    }

                }
                
                public class TestClass {


                                public static void main(String[] args) {
                                    // TODO code application logic here

                                    Rock r=new Rock()    //Anonymous class is an object alongwith body 
                                    {
                                      public void color()
                                      {
                                          System.out.println("color is black");
                                      }
                                    };    //always remembers to put semi-colon over here
                                  r.color();
                                    


                                }

                            }

                
                

Output

                color is black.
                

Anonymous class also has variation, in which it implements the interface.Dont get tricked away by instance of the interface. As we know we cannot instantiate interface.

                interface Sportsman {
                public void category();
                                    }
                                    class Olympic {
                                    public static void main(String args[])
                                            {
                                            Sportsman c = new Sportsman() {
                                            public void category() {
                                            System.out.println("Hi, I am a Athlete");
                                                                    }
                                                                            };
                                            c.category();
                                            }
                                                  }
                
                

output

                Hi, I am a Athlete
                
                

Dont be fooled that interface Sportsman object is created, rather it an subclass that implements the interface.

Anonymous class can override the parent's class method, but cannot define its new method.

                class Food
{
	public void taste()
	{
	System.out.println("Taste is sweet");
	}

}

public class FoodMain
{
	static Food f=new Food()
	{
		public void taste()
		{
		System.out.println("Taste is sweeter");
		}
		
		public void tasteBud()
		{
		System.out.println("your taste sucks");
		}
		
		
	
	};
	
	public static void main(String args[])
	{
		f.taste();
		f.tasteBud();
		
	}


}
                
                
                
                
Output
                FoodMain.java:31: error: cannot find symbol
                f.tasteBud();
                 ^
                 symbol:   method tasteBud()
                location: variable f of type Food
                1 error
                
                

As the output shows,we get error if we defined new method in Anonymous class and call it.


We can also defined anonymous class in argument.

                class Dogs{

	public void bark()
	{
	System.out.println("bark and bite");
	}

}

class PackMain
{

Dogs dogs;
	public void setDogs(Dogs d)
	{
	dogs=d;
	d.bark();
	}

	public static void main(String args[])
	{
	PackMain p=new PackMain();
	p.setDogs(new Dogs()
												{
													public void bark()
													{
													System.out.println("only Bark");
													}
												}
	);
	}


}
                
                
output
                only Bark
                

As the output shows "only Bark", a new anonymous class is created and passed as argument to setDogs().

Remember that while creating Anonymous class and passing as arguments,semi-colon (;) should not be after end of class defination but after method in which it is passed as argument.