Pages

Tuesday, January 24, 2017

Methods

Methods provides functionality or behaviour of an object.

Syntax:
[modifiers] <returnType> <methodName> (<params>)
{
    //Method implementation.
}

Types of Methods:

  1. Instance methods
  2. Static methods

Instance Methods

  • Methods defined inside the class without using the static modifier are called as Instance methods.

Static Methods

  • Methods defined inside the class with using static modifier are called as Static methods.
Ex:
class Hello{
    void m1(){ //INSTANCE METHOD
    }
    
    static void m2(){ //STATIC METHOD`
    }
}

class Test{
    Hello h = new Hello();
    h.m1(); //VALID
    h.m2(); //VALID
    
    Hello.m1(); //INVALID
    Hello.m2(); //VALID
    
    Hello h = null;
    h.m1(); //INVALID
    h.m2(); //VALID
}
  • Instance methods must be invoked with the reference variable which contains the object.
  • Static methods can be invoked in 3 ways:
    1. With Class Name
    2. With the reference variable which contains null
    3. With the reference variable which contains Object.

Methods Return Type

  • Method can return a result in 2 ways:
    1. Using the result inside the method.
    2. Returning the result to the caller method.
  • If you want to return the result to the caller of the method, then the return type (data type) needs to be specified.
  • When you don't want to return the result of a method to the caller of the method, then you must specify return type as void.

Example 1:

class Lab11{
    public static void main(String args[]){
        Manager mg = new Manager();
        mg.setAge(-12);
    }
}

class Manager{
    int age=18;
    void setAge(int age){
        if(age<18)
            return;
        this.age = age;
        
    }
}

/*
Though the return type of the method is void,
empty return statements are allowed in the methods with void as return type.
*/

Example 2:

class Lab12{
    public static void main(String args[]){
        Manager mg = new Manager();
        mg.setAge(-12);
    }
}

class Manager{
    int age=18;
    void setAge(int age){
        if(age<18)
            return 0; //You are not allowed to return anything when the return type mentioned in the method is void.
        this.age = age;
        
    }
}

/*
Lab12.java:12: error: incompatible types: unexpected return value
                        return 0;
                               ^
1 error
*/

Example 3:

class Lab12{
    public static void main(String args[]){
        Manager mg = new Manager();
        int a = mg.show(10);
        System.out.println(a);
        System.out.println(mg.show(10)); //if a method returns something, it can be directly executed from SOP
    }
}

class Manager{
    int show(int x){
        return x+1;
    }
        
    }
}

/*
output:
11
11
*/

Example 4:

class Lab14{
    public static void main(String args[]){
        Manager mg = new Manager();
        mg.show(10); //returned value will be discarded
        System.out.println("done");
    }
}

class Manager{
    int show(int x){
        return x+1;
    }
        
}
/*
output:
done
*/

Example 5:

If the method return type is specified in the method declaration, then you cannot use an empty return statement (as good as not returning anything. Only the control is transferred back to the caller). The return statement should return the datatype.
class Lab16{
    public static void main(String args[]){
        Manager mg = new Manager();
        mg.show(10); //returned value will be discarded
        System.out.println("done");
    }
}

class Manager{
    int show(int x){
        System.out.println("show()");
        return;
    }
        
}

/*
Lab16.java:12: error: incompatible types: missing return value
                return;
                ^
1 error
*/

Example 6:

class Lab17{
    public static void main(String args[]){
        Manager mg = new Manager();
        mg.show(10); //returned value will be discarded
        System.out.println("done");
    }
}

class Manager{
    int show(int x){
        System.out.println("show()");
        return 12L;
    }
        
}

/*
The return type expected is int, but a long type is returned. This needs explicit casting
C.T.E
Lab17.java:12: error: incompatible types: possible lossy conversion from long to int
                return 12L;
                       ^
1 error
*/

Example 7:

class Lab18{ 
    public static void main(String args[]){ 
        Manager mg = new Manager(); mg.show(10); //returned value will be discarded 
        System.out.println("done"); 
    } 
} 
    
class Manager{ 
    int show(int x){ 
        System.out.println("show()"); 
        return 'A'; 
    } 
} 
/* Here the datatype of the returned value is char is implicitly converted to an int. Output: show() done */

Example 8:

class Lab19{
    public static void main(String args[]){
        Manager mg = new Manager();
        mg.show(10); //returned value will be discarded
        System.out.println("done");
    }
}

class Manager{
    long show(int x){
        System.out.println("show()");
        return x+1;
    }
        
}

/*
Here the datatype of the returned value is int, what is expected is long
int is implicitly converted to long.

Output:
show()
done

*/

Example 9:

class Lab20{
    public static void main(String args[]){
        Manager mg = new Manager();
        System.out.println(mg.show(10)); 
        System.out.println("done");
    }
}

class Manager{
    boolean show(int x){
        System.out.println("show()");
        return false;
        return false;
    }
        
}

/*
C.T.E
cannot have more than 1 return statement inside a block
Lab20.java:13: error: unreachable statement
                return false;
                ^
1 error

*/

Example 10:

class Lab23{
    public static void main(String args[]){
        Manager mg = new Manager();
        System.out.println(mg.isDigit('A')); 
        System.out.println(mg.isDigit('8'));
    }
}

class Manager{
    boolean isDigit(char ch){
        System.out.println("isDigit(): "+ch);
        if(ch >=48 && ch<=57){
            return true;
        }else{
            return false;
        }
    }
        
}

/*
isDigit(): A
false
isDigit(): 8
true
*/

Method Parameters

There are two types of argument:
  • Formal Argument
  • Actual Argument
Formal Argument: Arguments specified with the method definition or declaration are called as Formal Arguments. Formal arguments are called as Parameters

class Hello{
    void show(int a, int b){ //Formal arguments
    ...
    }
}

Actual Argument:
Arguments specified with the method call are called as Actual Arguments.




Hello h = new Hello();
h.show(10,20); //Actual arguments

Example 11:

class Lab29{
    public static void main(String args[]){
        Hello h = new Hello();
        h.show((65));
    }
}

class Hello{
    void show(char x){
        System.out.println("show(char)");
    }
}


/*
Lab29.java:4: error: incompatible types: possible lossy conversion from int to char
                h.show((65));
                       ^
Note: Some messages have been simplified; recompile with -Xdiags:verbose to get full output
1 error
*/

Example 12:

class Lab28{
    public static void main(String args[]){
        Hello h = new Hello();
        h.show((byte)12);
    }
}

class Hello{
    void show(byte x){
        System.out.println("show(byte)");
    }
}

/*
show(byte)
*/

Method Overloading

  • You can write multiple methods inside the class with the same name by changing the parameters. This process is called METHOD OVERLOADING.
  • When you are overloading methods, the following rules must be followed:
  • Method name must be same.
  • Method parameter must be changed in terms of
    1. Number of parameters
    2. Datatype of parameters
    3. Order of parameters
  • Overloading can be achieved even if the return type doesn't match, .
  • Overloading can be achieved even if the access level is different, .
  • Overloading can be achieved even if one overloaded method is marked "static" or "abstract".

Example 12:

class Lab35{
    public static void main(String args[]){
        Hello h = new Hello();
        
        String a = h.add(99,"BNG");
        System.out.println(a);
        
        String b = h.add("BNG",99);
        System.out.println(b);
        
    }
}

class Hello{
    String add(int a, String b){
        System.out.println("add(int, int)");
        return a+b;
    }
    String add(String a, int b){
        System.out.println("add(String, int)");
        return a+b;
    }
}

/*
add(int, int)
99BNG
add(String, int)
BNG99
*/

Example 13:

class Lab39{
    public static void main(String args[]){
        Hello h = new Hello();
        byte b = 20;
        h.add(b,b);
    }
}

class Hello{
    
    void add(byte a, int b){
        System.out.println("add(byte a, int b)");
    }
    
    void add(int a, byte b){
        System.out.println("add(int a, byte b)");
    }
}

/*
C.T.E

Lab39.java:5: error: reference to add is ambiguous
                h.add(b,b);
                 ^
  both method add(byte,int) in Hello and method add(int,byte) in Hello match
1 error*/

Example 14:

class Lab41{
    public static void main(String args[]){
        Hello h = new Hello();
        h.show('A','B');
    }
}

class Hello{
    
    void show(int a, char b){
        System.out.println("show(int,char)");
    }
    
    void show(long a, char b){
        System.out.println("show(long,char)");
    }
}

/*
output:
show(int,char)
*/

Example 15:

class Lab41{
    public static void main(String args[]){
        Hello h = new Hello();
        h.show('A','B');
    }
}

class Hello{
    
    void show(int a, char b){
        System.out.println("show(int,char)");
    }
    
    void show(long a, char b){
        System.out.println("show(long,char)");
    }
}

/*
output:
show(int,char)
*/

Example 16:

class Lab42{
    public static void main(String args[]){
        Hello h = new Hello();
        h.show('A','B');
    }
}

class Hello{
    
    void show(int a, int b){
        System.out.println("show(int,int)");
    }
    
    void show(long a, long b){
        System.out.println("show(long,long)");
    }
}

/*
show(int,int)
*/

Example 17:

class Lab43{
    public static void main(String args[]){
        Hello h = new Hello();
        h.show('A','B');
    }
}

class Hello{
    
    void show(int a, int b){
        System.out.println("show(int,int)");
    }
    
    void show(long a, char b){
        System.out.println("show(long,char)");
    }
}

/*
Lab43.java:4: error: reference to show is ambiguous
                h.show('A','B');
                 ^
  both method show(int,int) in Hello and method show(long,char) in Hello match
1 error
*/

Example 18:

class Lab44{
    public static void main(String args[]){
        Hello h = new Hello();
        h.show(null);
        h.show("BNG");
        h.show(h);
    }
}

class Hello{
    
    void show(String str){
        System.out.println("show(String)");
    }
    
    void show(Object str){
        System.out.println("show(Object)");
    }
}

/*
output:
show(String)
show(String)
show(Object)
*/

Example 19:

class Lab45{
    public static void main(String args[]){
        Hello h = new Hello();
        h.show(null);
    }
}

class Hello{
    
    void show(String str){
        System.out.println("show(String)");
    }
    
    void show(Hello str){
        System.out.println("show(Hello)");
    }
}

/*
Lab45.java:4: error: reference to show is ambiguous
                h.show(null);
                 ^
  both method show(String) in Hello and method show(Hello) in Hello match
1 error
*/

Example 20:

class Lab49{
    public static void main(String args[]){
        //System.out.println(10); println(int) method is executed.
        //System.out.println(10L); println(long) method is executed.
        System.out.println(10,20);
    }
}
/*
C.T.E

Lab49.java:3: error: no suitable method found for println(int,int)
                System.out.println(10,20);
                          ^
    method PrintStream.println() is not applicable
      (actual and formal argument lists differ in length)
    method PrintStream.println(boolean) is not applicable
      (actual and formal argument lists differ in length)
    method PrintStream.println(char) is not applicable
      (actual and formal argument lists differ in length)
    method PrintStream.println(int) is not applicable
      (actual and formal argument lists differ in length)
    method PrintStream.println(long) is not applicable
      (actual and formal argument lists differ in length)
    method PrintStream.println(float) is not applicable
      (actual and formal argument lists differ in length)
    method PrintStream.println(double) is not applicable
      (actual and formal argument lists differ in length)
    method PrintStream.println(char[]) is not applicable
      (actual and formal argument lists differ in length)
    method PrintStream.println(String) is not applicable
      (actual and formal argument lists differ in length)
    method PrintStream.println(Object) is not applicable
      (actual and formal argument lists differ in length)
1 error
*/

Example 21:

class Lab52{
    public static void main(String args[]){
        System.out.println(null);
    }
}

/*
Lab52.java:3: error: reference to println is ambiguous
                System.out.println(null);
                          ^
  both method println(char[]) in PrintStream and method println(String) in PrintStream match
1 error
*/

Call by Value / Call by Reference

Call by Value:
When you invoke a method by passing primitive data types then it is called as CALL BY VALUE. In this case, any change happening inside the called method will not be reflected in the caller method.

Call by Reference
When you invoke a method by passing reference data type then it is called as CALL BY REFERENCE. 

a. Any modifications done to the property of the object inside the called method will be reflected to the caller method.
b. If the reference itself is modified then modifications happened inside the called method will not be reflected to caller method.


Example 22:

Call by Value
class Lab53 
{
    public static void main(String[] args) 
    {
        int a = 99;
        Hello h = new Hello();
        System.out.println("main begin :"+a);
        h.m1(a);
        System.out.println("main ends :"+a);
    }
}

class Hello
{
    void m1(int a){
        System.out.println("m1 begin: "+a);
        a=a+10;
        System.out.println("m1 ends : "+a);
    }
}

/*
Ouput:
main begins :99
m1 begins :99
m1 ends : 109
main ends: 99
*/

Example 23:

Call by Reference
class Lab54 
{
    public static void main(String[] args) 
    {
        Hai hai = new Hai();
        hai.a = 99;

        Hello hello = new Hello();
        System.out.println("main begins: "+hai.a);
        hello.m1(hai);
        System.out.println("main ends: "+hai.a);

    }
}

class Hello
{
    void m1(Hai hai){
        System.out.println("m1 begins: "+hai.a);
        hai.a=hai.a+10;
        System.out.println("m1 ends: "+hai.a);
    }
}

class Hai
{
    int a;
}


/*
output:
main begins: 99
m1 begins :99
m1 ends: 109
main ends: 109

*/

Example that demonstrates swapping variables using static/instance overloaded methods

public class SwapMe{
    int var1;
    int var2;
    
    SwapMe(int var1, int var2){
        this.var1 = var1;
        this.var2 = var2;
    }
    
    void swapByRef(){
        System.out.println("Calling swapByRef() - instance method : ");
        int temp = this.var1;
        this.var1 = this.var2;
        this.var2 = temp;
        System.out.println("var1 - "+this.var1+"\t var2 - "+this.var2);
    }
    
    static void swapByRef(SwapMe t1){
        System.out.println("Calling swapByRef() - static method : ");
        int temp = t1.var1;
        t1.var1 = t1.var2;
        t1.var2 = temp;
        System.out.println("var1 - "+t1.var1+"\t var2 - "+t1.var2);
    }
    
    void show(){
        System.out.println("var1 - "+this.var1+"\t var2 - "+this.var2);
    }
    
    public static void main(String[] args) {
        
        SwapMe t1 = new SwapMe(1, 2);
        System.out.println("Before Swapping:");
        t1.show();
        System.out.println("----------------------------------------");
        System.out.println("After Swapping using instance method");
        t1.swapByRef();
        System.out.println("----------------------------------------");
        System.out.println("After Swapping using static method");
        SwapMe.swapByRef(t1);   
    }   
}

Summary:

  1. Instance and static members can be accessed from instance methods.
  2. Only static members can be accessed from static methods.
  3. When return type is void, then:
    1. You should not specify return statement.
    2. You can specify empty return statement.
  4. When return type NOT is void, then:
    1. You must specify return statement.
    2. You should not specify EMPTY RETURN statement.
  5. Return values must be same or compatible to the return type.
  6. Actual arguments and formal arguments must be
    1. Same in terms of number of arguments.
    2. Same or compatible in terms of type of arguments.
    3. Same in terms of order of arguments.

Sunday, January 22, 2017

Using a Instance/Static/Local variable before declaring it and Blank final variable


Using a Instance/Static/Local variable before declaring it.


Summary

  1. Scope of Local variables starts from its declaration statement and it goes upto end of the Block where it is declared
  2. Local variables must be accessed from or after declaration statement.
  3. Class Level variables can be declared anywhere in the class. It can be accessed from other members.
  4. You can access class level variable from method, constructors directly.
  5. When static variables declared after static initialization block then remember following:
    1. You can initialize the variable directly.
    2. You cannot access the value of the variable directly.
    3. When you access value of variable directly, compiler will generate error called : "Illegal forward reference error"
    4. You can access the value of the variable with class name.
  6. When instance variables declared after instance initialization block then remember following points:
    1. You can initialize the variable directly.
    2. You cannot access the value of the variable directly.
    3. When you access value of the variable directly, compiler will generate error called "Illegal forward reference"
    4. You can access the value of the variable with this keyword.
  7. When you declare instance variables and initialization blocks then initialization of the variables and execution of the initialization blocks will be in the same order as defined in the class.
  8. final instance variable can be initialized from the constructor also but it must be initialized from all the constructors if available.
  9. When final instance variable initialized from the IIB then that variable cannot be initialized from constructor.
  10. final static variable must be initialized from SIB only; it can't be initialized from the constructors or IIB.
  11. Class loading is the process of reading the required class file and storing that information in the memory.
  12. Class will be loaded only once in the memory by the JVM. After loading the class if you delete the class file then also the application will be executed.
  13. Class will be loaded in the memory by the JVM when first time the member of the class will be used by JVM:
    1. When you are executing the class with java.exe then class will be loaded and static block will be executed. From Java 7, if you don't have main method, then class won't be loaded and static block won't be executed.
    2. When you create the object of the class and before this statement no other member of the class is used, then class will be loaded.
    3. When you access static members of the class and before this statement no other member of the class is used then class will be loaded.
    4. When you access the final static variable that is initialized in the same statement then JVM wont execute the static block.
      class Lab{
          public static void main(String args[]){
              System.out.println(Hello.a);
          }
      }
      
      class Hello{
          final static int a = 10;
          static{
              System.out.println("ST Block"); 
          }
      }
      
      
    5. When you define the reference variable but not using any members of the class then class will not be loaded.
      class Lab{
          public static void main(String args[]){
              Hello h = null;
          }
      }
      
      

Example 1:

Accessing a variable before declaration:

class Lab25{
    public static void main(String args[]){
        System.out.println(a);
        int a = 10;
    }

    static{
        System.out.println(b);
        int b = 10;
    }
}

/*
Lab25.java:3: error: cannot find symbol
                System.out.println(a);
                                   ^
  symbol:   variable a
  location: class Lab25
Lab25.java:8: error: cannot find symbol
                System.out.println(b);
                                   ^
  symbol:   variable b
  location: class Lab25
2 errors
*/

Example 2:

Value can be assigned to the variable before declaring, but cannot be accessed (using print statements)

class Lab27{
    public static void main(String args[]){
        System.out.println(Hello.b);
    }
}

class Hello{
    static{
        b = 10;
        Hello.b=10; //either of the two statements are valid
    }
    static int b = 90;
}

/*
output
90
(Since the static blocks/variables are executed in the order as they are written.)
No C.T.E in line - b=10 since here value is assigned to the variable.
*/

Example 3

Illegal forward reference error when variable is used directly.
class Lab29{
    public static void main(String args[]){
        System.out.println(Hello.b);    
    }
}

class Hello{
    static{
        System.out.println(b);
    }
    static int b = 90;
}

/*
Lab29.java:11: error: illegal forward reference
                System.out.println(b);
                                   ^
1 error
*/

Example 4

When a static variable is used using class reference, Illegal forward reference error is not thrown.
class Lab30{
    public static void main(String args[]){
        System.out.println("Main :"+Hello.b);   
    }
}

class Hello{
    static{
        System.out.println("SB:"+Hello.b);
    }
    static int b = 20;
}

/*
SB:0
Main:20
*/

Example 5:

Illegal forward reference error. Cannot reference a field before its defined.
class Lab33{
    public static void main(String args[]){
        System.out.println("Main :"+Hello.b);
    }

}

class Hello{
    static int a=10;
    static{
        System.out.println("SB1:"+a);
        System.out.println("SB1:"+b); //cannot access a field before it's declared.
    }
    
    static int b = 20;
    
    static{
        System.out.println("SB2:"+a);
        System.out.println("SB2:"+b);
    }
}

/*C.T.E
Lab33.java:13: error: illegal forward reference
                System.out.println("SB1:"+b); //cannot access a field before it's declared.
                                          ^
1 error
*/

Example 5:

Static variable can be accessed using Class name before declaration.
class Lab34{
    public static void main(String args[]){
        System.out.println("Main :"+Hello.b);
        
    }

}

class Hello{
    static int a=10;
    static{
        System.out.println("SB1:"+a);
        System.out.println("SB1:"+Hello.b); 
    }
    
    static int b = 20;
    
    static{
        System.out.println("SB2:"+a);
        System.out.println("SB2:"+b);
    }
    
}

/*output:
SB1:10
SB1:0
SB2:10
SB2:20
Main:20
*/

Example 6 :

Value can be assigned to an instance variable before declaration directly or using "this" keyword.
class Lab35{
    public static void main(String args[]){
        Hello h = new Hello();
        System.out.println(h.a);
    }
}

class Hello{
    {
        a=90;
        this.a=90;//can be used without any error.
    }
    int a = 20;
}

/*
output:
20
*/

Example 7:

Cannot access an instance variable directly before declaring it.

class Lab37{
    public static void main(String args[]){
        Hello h = new Hello();
        System.out.println(h.a);   
    }
}

class Hello{
    {
        System.out.println(a); //cannot access variable before it is declared.
    }
    int a = 20;
}

/*
Lab37.java:12: error: illegal forward reference
                System.out.println(a); //cannot access variable before it is declared.
                                   ^
1 error
*/

Example 8:

An instance variable can be used (print statement) using the "this" keyword before declaring it.

class Lab38{
    public static void main(String args[]){
        Hello h = new Hello();
        System.out.println(h.a);
        
    }
}

class Hello{
    {
        System.out.println(this.a);
    }
    int a = 20; 
}

/* 
output:
0
20
*/

Example 9:

Accessing an instance variable inside an Instance block before declaring it.
class Lab41{
    public static void main(String args[]){
        Hello h = new Hello();
        System.out.println(h.a);    
    }
}

class Hello{
    int a = 10;
    {
        System.out.println("IB1:"+a);
        System.out.println("IB1:"+b); //cannot access variable before its declared.
    }
    int b = 20;
    {
        System.out.println("IB2:"+a);
        System.out.println("IB2:"+b);
    }   
}

/*
C.T.E
Lab41.java:14: error: illegal forward reference
                System.out.println("IB1:"+b); //cannot access variable before its declared.
                                          ^
1 error
*/

Example 10:

Accessing an instance variable using "this" keyword inside an Instance block before declaring it.
class Lab42{
    public static void main(String args[]){
        Hello h = new Hello();
        System.out.println("Main :"+h.a);
        
    }

}

class Hello{
    int a = 10;
    {
        System.out.println("IB1:"+a);
        System.out.println("IB1:"+this.b); 
    }
    int b = 20;
    {
        System.out.println("IB2:"+a);
        System.out.println("IB2:"+b);
    }
    
}


/*
IB1:10
IB1:0
IB2:10
IB2:20
Main:10
*/

Example 11:

Instance Initializer blocks/statements(declarations) are always called before the Constructor is called.
class Lab44{
    public static void main(String args[]){
        Hello h = new Hello();
        System.out.println("Main :"+h.a);
        
    }

}

class Hello{
    {
        System.out.println("IIB: "+this.a);
    }
    Hello(){
        System.out.println("Con: "+a);
    }
    int a = 10;
    
}

/*
output :
IIB:0
Con:10
Main:10
*/

Example 12:

Order of execution of Static blocks, Instance blocks and Static initializers
class Lab51{
    public static void main(String args[]){
        System.out.println("Main :"+Hello.a);
        
    }
}

class Hello{
    static int a = 10;
    static Hello h1 = new Hello();
    {
        System.out.println("IB:");
    }
    
    static{
        System.out.println("SB:");
    }   
    
    static Hello h2 = new Hello();
}

/*
IB:
SB:
IB:
Main:10
*/

Example 13:

Blank final variable
class Lab58{
    public static void main(String args[]){
        Hello h = new Hello();
        System.out.println(h.a);
        
    }
}

class Hello{
    final int a;
}

/*
C.T.E
Blank final variable is not allowed.


Lab58.java:10: error: variable a not initialized in the default constructor
        final int a;
                  ^
1 error
*/

Example 14:

Blank instance final variable can be initialized inside a constructor, but if there are more than 1 constructors, then it has to be initialized in all of them.
class Lab60{
    public static void main(String args[]){
        Hello h = new Hello();
        System.out.println(h.a);
        
    }
}

class Hello{
    final int a;
    Hello(){
        a=10;
    }
    
    Hello(int a){}
}

/*
C.T.E
final variable is initialized only in 1 constructor and not in the other constructor.
*/

Example 15:

Blank final variable can be initialized using the this keyword also inside the constructors.
class Lab61{
    public static void main(String args[]){
        Hello h = new Hello();
        System.out.println(h.a);
        
    }
}

class Hello{
    final int a;
    Hello(){
        a=10;
    }
    
    Hello(int a){
        this.a=a;
    }
}

/*
10
*/

Example 16:

Blank final variable cannot be initialized in both the constructors and IIB's. It should be initialized either in all constructors or in IIB.
class Lab62{
    public static void main(String args[]){
        Hello h = new Hello();
        System.out.println(h.a);
        
    }
}

class Hello{
    final int a;
    Hello(){
        a=10;
    }
    
    {
        a=90;
    }
}

/*
C.T.Exception
Lab62.java:12: error: variable a might already have been assigned
                a=10;
                ^
1 error

Since IIB is executed before a constructor is executed.

*/

Example 17:

Blank static final variable cannot be initialized inside IIB's or Constructor.
class Lab63{
    public static void main(String args[]){
        Hello h = new Hello();
        System.out.println(h.a);
        
    }
}

class Hello{
    static final int a;
    {
        a=90;
    }
}

/*
C.T.E
Lab63.java:12: error: cannot assign a value to final variable a
                a=90;
                ^
1 error
*/

Example 18:

class Lab64{ public static void main(String args[]){ Hello h = new Hello(); System.out.println(h.a); } } class Hello{ static final int a; Hello(){ a=90; } } /* Lab64.java:12: error: cannot assign a value to final variable a a=90; ^ 1 error */

Example 19:

Blank static final variable can be initialized inside Static block.
class Lab66{
    public static void main(String args[]){
        Hello h = new Hello();
        System.out.println(h.a);
        
    }
}

class Hello{
    static final int a;
    static {
        System.out.println("St block: "+Hello.a);
        a=10;
    }
}

/*
St block: 0
10
*/

Example 20:

class Lab68{
    public static void main(String args[]){
        Hello h = new Hello();
        System.out.println(h.a);
        
    }
}

class Hello{
    static final int a;
    static {
        a=10;
        System.out.println("St block: ");
    }
}

/*

St block
10
*/

Constructors and this keyword

  1. Constructors are the special methods whose name is same as Class name.
  2. Constructors do not have return type.
  3. Constructors are invoked by the JVM automatically at the time of object creation.
  4. Constructors are mainly used to initialize instance variables of class with different set of values.
Example 1:

class Lab7{
    public static void main(String args[]){
        
        Student st1 = new Student();
        st1.show();
        Student st2 = new Student(11, "Bangalore");
        st2.show();
        Student st3 = new Student(22, "Bangalore", "Bangalore@xxx.com");        st3.show();
        Student st4 = new Student(33, "Bangalore", "Bangalore@ggg.com", 5656565);        st4.show();
        
        
    }
}

class Student{
    int sid;
    String sname;
    String email;
    long phone;
    
    Student(){
        System.out.println("Student default constructor");
    }
    
    Student(int id, String sn){
        System.out.println("Student 2-Arg Default Constructor");
        sid = id;
        sname = sn;
    }
    
    Student(int id, String sn, String em){
        System.out.println("Student 3-Arg Default Constructor");
        sid = id;
        sname = sn;
        email = em;
    }
    
    Student(int id, String sn, String em, long ph){
        System.out.println("Student 4-Arg Default Constructor");
        sid = id;
        sname = sn;
        email = em;
        phone = ph;
    }
    
    void show(){
        System.out.println(sid+"\t"+sname+"\t"+email+"\t"+phone);
    }
} 

Example 2:

class Lab14{
    public static void main(String args[]){
    
        Student st1 = new Student(-11);
        st1.show();     
    }
}

class Student{
    int age = 18;
    
    Student(int ag){
        System.out.println("Student 1-Arg Default Constructor");
        if(age<18){
            return;
        }
        age = ag;
    }
        
    void show(){
        System.out.println(age);
    }
} 


/*
empty return statements are allowed in Constructors as they do not provide a return type.
*/

this keyword

  1. this is a keyword which acts as a reference variable.
  2. this reference variable contains address of current object.
  3. this is an instance reference variable and cannot be accessed from static context.
  4. this keyword can be used in three ways:
    • To access the variable
      Syntax:
          this.<variableName>
      Ex:
          this.a;
          this.b;
      
    • To access the methods:
      Syntax:
          this.<methodName>();
      Ex:
          this.m1();
          this.m2();
      
    • To access the overloaded constructor:
      Syntax:
          this(params);
          
      Ex:
          this();     //-> invokes Default constructor
          this(99);   //-> invokes 1-Arg constructor
          this(99,88) //-> invokes 2-Arg constructor
      

  5. this is a final variable. It cannot be modified.
    Ex:
        this = null;
        this = new <ClassName>;
    //this is not allowed
    

Example 1:

In the below example, the arguments are assigned to itself inside the Constructor, therefore the output value is default values


class Lab5{
    public static void main(String args[]){
        Student st1 = new Student(1, "Bangalore");
        st1.show();
        
        Student st2 = new Student(2, "Karnataka");
        st2.show();
    }
}

class Student{
    int sid;
    String sname;
    
    Student(int sid, String sname){
        System.out.println("Student 2-arg constructor");
        sid=sid;
        sname=sname;
    }
    void show(){
        System.out.println(sid+"\t"+sname);
    }
}

/*

Output:
Student 2-arg constructor
0 null
0 null
*/

Example 2:

class Lab6{
    public static void main(String args[]){
        Student st1 = new Student(11, "Bangalore");
        st1.show();
        
        Student st2 = new Student(22, "Karnataka");
        st2.show();
    }
}

class Student{
    int sid;
    String sname;
    
    Student(int sid, String sname){
        System.out.println("Student 2-arg constructor");
        this.sid=sid;
        this.sname=sname;
    }
    void show(){
        System.out.println(sid+"\t"+sname);
    }
}

/*

Output:
Student 2-arg constructor
11  Bangalore
22 Karnataka
*/

Example 3:

class Lab12{
    public static void main(String args[]){
        Student st1 = new Student(11, "Bangalore", "Bangalore@GGG.com", 4566545);
        st1.show();
    }
}

class Student{
    int sid;
    String name;
    String email;
    long phone;
    
    Student(){
        System.out.println("Student DC");
    }
    
    Student(int sid){
        this.sid = sid;
        System.out.println("Student 1-arg");
    }
    
    Student(int sid, String name){
        this.sid = sid;
        this.name = name;
        System.out.println("Student 2-arg");
    }
    
    Student(int sid, String name, String email){
        this.sid = sid;
        this.name = name;
        this.email = email;
        System.out.println("Student 3-arg");
    }
    
    Student(int sid, String name, String email, long phone){
        this.sid = sid;
        this.name = name;
        this.email = email;
        this.phone = phone;
        System.out.println("Student 4-arg");
    }
    
    void show(){
        System.out.println(sid+"\t"+name+"\t"+email+"\t"+phone);
    }
}

/*output:
Student 4-arg
11      Bangalore     Bangalore@GGG.com     4566545
*/

Example 4:

class Lab13{
    public static void main(String args[]){
        Student st1 = new Student(11, "Bangalore", "Bangalore@GGG.com", 4566545);
        st1.show();
    }
}

class Student{
    int sid;
    String name;
    String email;
    long phone;
    
    Student(){
        System.out.println("Student DC");
    }
    
    Student(int sid){
        this();
        this.sid = sid;
        System.out.println("Student 1-arg");
    }
    
    Student(int sid, String name){
        this(sid);
        this.name = name;
        System.out.println("Student 2-arg");
    }
    
    Student(int sid, String name, String email){
        this(sid, name);
        this.email = email;
        System.out.println("Student 3-arg");
    }
    
    Student(int sid, String name, String email, long phone){
        this(sid, name, email);
        this.phone = phone;
        System.out.println("Student 4-arg");
    }
    
    void show(){
        System.out.println(sid+"\t"+name+"\t"+email+"\t"+phone);
    }
}


/*output:
Student DC
Student 1-arg
Student 2-arg
Student 3-arg
Student 4-arg
11      Bangalore     Bangalore@GGG.com     4566545
*/

Example 5:

Recursive constructor invocation
class Lab14{
    public static void main(String args[]){
        Hello h1 = new Hello();
    }
}

class Hello{
    Hello(){
        this();
    }
}

/*
Lab14.java:8: error: recursive constructor invocation
        Hello(){
        ^
1 error
*/

Example 6:

Recursive constructor invocation:
class Lab15{
    public static void main(String args[]){
        Hello h1 = new Hello();
    }
}

class Hello{
    Hello(){
        this(10);
    }
    
    Hello(int i){
        this();
    }
}

/*

C.T.E
Lab15.java:12: error: recursive constructor invocation
        Hello(int i){
        ^
1 error
*/

Example 7:

this is final and it cannot be changed.
class Lab20{
    public static void main(String args[]){
        Hello h = new Hello();
        //h.show();
    }
}

class Hello{
    void show(){
        this = null;
        this=new Hello();
    }
}


/*

Lab20.java:10: error: cannot assign a value to final variable this
                this = null;
                this = new Hello();
                ^
2 errors
*/

Example 8:

Assigning Incompatible reference variables using this.
class Lab22{
    public static void main(String args[]){
        new Hello().show();
        new Hai().show();
        
    }
}

class Hello{
    void show(){
        Hello h1 = this;
        Hai h2 = this;
    }
}

class Hai{
    void show(){
        Hello h1 = this;
        Hai h2 = this;
    }
}

/*
C.T.E

F:\JLC Programs\OOPS\this keyword\src>javac -d ..\classes Lab22.java
Lab22.java:12: error: incompatible types: Hello cannot be converted to Hai
                Hai h2 = this;
                         ^
Lab22.java:18: error: incompatible types: Hai cannot be converted to Hello
                Hello h1 = this;
                           ^
2 errors
*/

Example 9:

this can be used with class name also
class Lab23{
    public static void main(String args[]){
        Hello h = new Hello();
        h.show();
    }
}

class Hello{
    int a;
    void show(){
        String a = "Bangalore";
        System.out.println(a);
        System.out.println(this.a);
        System.out.println(Hello.this.a);
    }
}

/*
Output:
Bangalore
0
0
*/


Summary : Constructors

  1. Constructor without any arguments is called Default Constructor.
  2. When you are not writing any constructor inside the class then one default constructor will be inserted by the Java Compiler.
  3. When you are writing any constructor inside the class then default constructor will not be inserted by the Java Compiler.
  4. You can write multiple constructors inside the class by changing parameters. This process is called as CONSTRUCTOR OVERLOADING.
  5. When you are overloading constructors then parameters must differ in terms of:
    • Number of parameters
    • Type of parameters
    • Order of parameters

    class Hello{
        int a;
        String str;
        Hello(int a, String str){...} //VALID
        Hello(int a, String str){...} //INVALID
        Hello(int a, int b){...} //VALID
        Hello(String str, int a){...} //VALID
    }
    
    
  6. You cannot invoke the constructor. Always JVM invokes automatically.
  7. You cannot specify the return type for the constructor. When you specify the return type for the constructor then it will be treated as normal method.
  8. You can use empty return statement inside the Constructor.

Summary :this keyword

  1. You can use the same name for local variables and instance variables.
  2. When you access any variable directly then the following things will happen:
    1. Checks whether that variable is declared in the local scope or not.
    2. If found in the local scope, that local variable will be used.
    3. If not found in the local scope, then checks whether that variable is declared in the class scope or not.
    4. If found, that class level variable will be used.
  3. When you have same name for local variables and class level variables then do the following:
    • Refer the local variable directly.
    • Refer the class level variable using this keyword.
  4. call to constructor using this must be from constructor only, not from methods and blocks.
    class Hello{
        Hello(){}
    
        Hello(int a){
            this(); //VALID
        }
    
        {
            this();//INVALID
        }
    
        void show(){
            this();//INVALID
        }
    }
    
    
  5. call to this must be first statement in the Constructor.
  6. The process of invoking one constructor from another constructor using this is called as CONSTRUCTOR CHAINING.
  7. this is an instance variable and cannot be referenced from static context.
  8. Local variables cannot be referred using this keyword.
  9. this is a final reference variable and cannot be modified.
    1. this = null; //INVALID
    2. this = new Hello(); //INVALID9
  10. this can be assigned to current class reference variable
    class Hello{
        void show(){
            Hello h1 = this; //VALID
            Hai h2 = this; //INVALID
        }
    }
    
    
    class Hai{
        void show(){
            Hello h1 = this; //INVALID
            Hai h2 = this; //VALID
        }
    }
    
    
  11. this keyword can be referred with current class name.
    class Hello{
        int a;
        void show(){
            System.out.println(Hello.this.a); //VALID
            System.out.println(Hai.this.a); //VALID
        }
    }