Java Basics – Modifiers

In Java when we write our classes, methods and fields then we need some have some some control over how and where these classes, methods and fields can be used. We can have this control by using Modifiers. Modifiers are special java keywords that allow us to fine grain the control over usage of class, methods and fields. Modifiers fall into two groups.

  1. Access Modifiers.
  2. Other Modifiers.

Access Modifiers

These modifiers let us control who can access the classes, methods and fields. There are three access modifiers namely

  1. public
  2. private
  3. protected

There is a 4th level of control which is popularly known as “default” access. When none of the access modifiers is used then the element (class, methods and fields) are said to have default access.

Private Access

Example – private void someMethod(){}

  1. This is most restrictive access modifier.
  2. Class cannot be declared private unless they are nested.
  3. A private method or field can be accessed only within the class they are declared.
  4. They cannot be inherited.

Public access

Example – public class Someclass{ }

  1. Least restrictive modifier.
  2. A public class, method or field can be access by any other piece of code in the system.

Protected Access

Example – protected int myInt;

  1. Also known as Inheritance access.
  2. Class cannot be declared protected unless it is a nested class.
  3. A protected member can be accessed by all the classes within the same package of containing class.
  4. A protected member can be accessed by all the subclasses which are not part of same package.

Default Access

Example class defaultClass

  1. default access is also known as package access.
  2. A default class can be accessed only within same package.
  3. A default method and field can be only accessed within same package.

To summarize

Same Class Package SubClass All
public yes yes yes yes
protected yes yes yes no
default yes yes no no
private yes no no no

Code Snippet

package com.aranin.corejava;

/**
 * Created by IntelliJ IDEA.
 * User: Niraj Singh
 * Date: 7/14/14
 * Time: 11:47 AM
 * To change this template use File | Settings | File Templates.
 */
public class AccessDemo {
    private int x = 10;

    protected void printx(){
        System.out.println(x);
    }

    void printdefaultx(){
        System.out.println(x*100);
    }

}

/*
This need to be commented. There can be only one public class per file.
Compiler Error -  Class 'SecondPublic is public, should be declared in file named SecondPublic.java'
public class SecondPublic{

}
 */

/**
 * it is ok to have a another class with default access
 */
class DefaultClass{
    public static void main(){
        AccessDemo ad =  new AccessDemo();
        /*
             ad.x will give compiler error in line below.
             x has private access in class com.aranin.corejava.AccessDemo
         */
        //System.out.println(ad.x);

        /*
        * can access protected in same package
        */

        ad.printx();

        /*
        * can access default in same package
        */

        ad.printdefaultx();

    }

}

Classes in another package

package com.aranin.corejava.another;

import com.aranin.corejava.AccessDemo;

/**
 * Created by IntelliJ IDEA.
 * User: Niraj Singh
 * Date: 7/14/14
 * Time: 11:58 AM
 * To change this template use File | Settings | File Templates.
 */
public class AnotherPackageClass extends AccessDemo{
    public int a = 100;

    public   AnotherPackageClass(){
        this.printx();
    }

    /*
    * Override and used protected is subclass allowed
     */
    protected void printx(){
        //can be access in subclass within other package
        super.printx();
        System.out.println(a);
    }

    /**
     * This is not overriding as printdefaultx in AccessDemo is not visible.
     */

    void printdefaultx(){
        System.out.println(a*100);
    }

    public static void main(String[] args){
        AccessDemo ad = new AccessDemo();
        AnotherPackageClass apd = new  AnotherPackageClass();

        //can't use here and printx is protected
        //ad.printx();

        //cant be done compiler error stating that  printdefaultx is not public
        //ad.printdefaultx();

        //can be done will print 100
        apd.printx();

        //can be done will print 10000
        apd.printdefaultx();

    }

}

Subclasses and overriding rules

In java a method cannot be overridden to be more private. So the rules are

  1. private method – Cannot be overridden.
  2. default method – Can be overridden by default, protected or public method.
  3. protected method – Can be overridden by protected or public method.
  4. public method – Can only be overridden by public method

Other Modifiers

Apart from access modifiers there are other modifiers which can be applied in java. They are

  1. final
  2. abstract
  3. static
  4. native
  5. transient
  6. volatile
  7. synchronized
  8. strictfp

final

final modifier can be applied to class, methods, fields and variables.

  1. final class cannot be inherited.
  2. final method cannot be overridden.
  3. final fields cannot be modified once initialized. They are know as constants.
  4. final methods and fields are inherited in same way as normal methods and fields however they cannot be modified or overridden.
package com.aranin.corejava;

/**
 * Created by IntelliJ IDEA.
 * User: Niraj Singh
 * Date: 7/14/14
 * Time: 12:11 PM
 * To change this template use File | Settings | File Templates.
 */
public class FinalDemo {
    public final int a;
    public final int b = 1;

    public FinalDemo(){
        // initialised once and now cannot be assigned another value
        a = 100;
       //variable a might already have been assigned
       //a++;

       System.out.println(a);
    }

    public final void doSomething(){
      System.out.println("final product : " + a*b);
    }

    public static void main(String[] args){
         FinalDemo finalDemo = new FinalDemo();
    }

}

class ExtendFinalDemo extends FinalDemo{

    /**
     *  doSomething() in com.aranin.corejava.ExtendFinalDemo cannot override doSomething() in 
     *  com.aranin.corejava.FinalDemo; overridden method is final
     */
    /*
    public final void doSomething(){
      System.out.println("final product : " + a*b);
    }   */

}

abstract

abstract modifier can be applied to class or method.

  1. abstract class cannot be instantiated.
  2. abstract method must be overridden.
  3. class containing abstract method must be declared abstract.
  4. child class must override the abstract methods of an abstract class else child class should be declared abstract.
  5. abstract method must not be private.
  6. constructor can not be abstract.
  7. fields cannot be abstract.

static

static modifier can be applied to methods, fields and code block. The only time static is applied for class is when they are nested class. Static members are not associated with any instance of class, at any time there is only one copy of the static member. They are initialized and created when the class is first loaded.

  1. static modifier can only be applied for methods and fields.
  2. Nested class can be static.
  3. Static members does not belong to instance of class. They belong to class only.
  4. There is only copy of static method and field. They are created when class is first loaded in JVM.
  5. static method cannot be overridden. Overriding is run time operation and is related to object. Static methods on other hand are not owned by object hence they cannot be overridden.
  6. Static methods cannot access fields and methods of enclosing class directly. They should obtain instance of class to access the members.
  7. When a class is loaded into JVM then all its static members are initialized in order they appear in class.
package com.aranin.corejava;

/**
 * Created by IntelliJ IDEA.
 * User: Niraj Singh
 * Date: 7/14/14
 * Time: 12:20 PM
 * To change this template use File | Settings | File Templates.
 */
public class StaticDemo {
    /**
     * static statments are run one by one when class is firt loaded. In this case the belore static block will run
     * before main is executed
     */
    static{
        System.out.println("I will be printed before main");
    }
    //final static int
    public static final int a;
    public static int b = 10;
    public int i = 100;

    /**
     * static intitializer block for intitializing a
     */
    static{
          a = 100;
    }

    public static void printi(){

        /**
         * non static variable i cannot be referenced from a static context
         */
        //System.out.println("i = " + i);
    }
    public static void prints(){
       System.out.println("I am prints in StaticDemo");
    }

    public static void main(String[] args){
        System.out.println("I am main i am the boss");
        System.out.println("a = " + a);
        System.out.println("b = " + b);
        StaticDemo.prints();
        StaticDemoSub.prints();
    }

    /**
     * can have static nested class
     */
    public static class StaticInner{

    }
}

/**
 * cant do
 * Modifier 'static' not allowed here
 */
/*
static class TopStatic{

}
*/

/**
 * demo for static method cannot be overridden
  */
class StaticDemoSub extends StaticDemo{

    /**
     * this appears to override prints in  StaticDemo but that is not the case.
     *  They are both different method
     */
    public static void prints(){
       System.out.println("I am prints in StaticDemoSub");
    }
}

native

  1. native modifier is applied only to methods.
  2. Applying native implies that the method is written in code other than java like C or ,C++.
  3. It is mostly used to import C,C++ libraries or low level stuff into java code.

transient

  1. transient modifier can only be applied to variables and not methods or classes.
  2. transient variables cannot be serialized. i.e if an object is serialized then all its transient variables are not.
public class TransientDemo implements Serializable{
     public int a = 10;
     //This will not be serialized hence credit card number cannot be 
     //saved into file
     private transient String creditCardNum;
}

volatile

  1. Only variables can be volatile.
  2. When a variable is declared volatile then it can be modified asynchronously.
  3. If multiple threads modify a volatile variable then they all get same value. So the state of volatile variable is always consistent for all the threads. So if you want a variable whose value is same for all the thread at a time then use volatile.
  4. volatile is used in creating consistent singleton classes in a multi-threaded system

synchronized

synchronized is used to control the access of a piece of resource by multiple threads. This is beyond scope of this post.

Phew! writing on basic stuff is tough. I hope all you folks enjoyed this post.

if(somethingwrong){
     please drop a comment
}else{
      drop a comment
}

Warm Regards

Niraj

Print Friendly, PDF & Email

About Niraj Singh

I am CEO and CoFounder of a startup "Aranin Software Private Limited, Bangalore. I completed my graduation in 2002 as an Aerospace Engineer from IIT Kharagpur. I love working on new ideas and projects and recently released my first open source project JaiomServer "http://jaiomserver.org". I have 9 years of experience in IT industries most of which I have spent in developing community applications for various clients using java. Some of the sites in which I have actively involved with are hgtv.com, food.com, foodnetwork.com, pickle.com, diynetwork.com etc.
This entry was posted in Core Java. Bookmark the permalink.