Learn Java from Scratch: Access modifiers in Java7 min read

modifier types: access modifers in java

Modifier Overview

We have learned about variables and data types in Java, I think now it’s a good time to introduce some concepts about modifier types in Java. Modifier types in Java play an important role that are used to change the meaning of a variable or method, or even class. Modifiers are Java keywords that give the compiler information about the nature of code, data, or classes. In Java, modifiers are categorized into two types:

  • Access modifier
  • Non-access modifier

In this article, we will first learn about access modifiers. non-access modifiers will be discussed in the next article.

Java Access modifier

Access modifiers in Java control which classes may use data, variables, nested classes, and constructors. There are 4 access modifiers in Java:

  • public: the most generous modifier in Java, which is visible anywhere.
  • protected: has scope within the package and all subclasses even in the different packages.
  • default: has scope only inside the same package.
  • private: the most restrictive modifier in Java, has only scope in the class it is declared but other classes can still access private code through the public getter method.

public

The most generous access modifier in Java is public. A class, method, constructor, interface, etc. declared public can be accessed from any other class. Any public method may be overridden by any subclass. An application declares its main() method to be public so that main() can be invoked from any Java runtime environment. For example:

public class PublicClass {
    public static int squared(int x){
        return x * x;
    }
}
class Main{
    public static void main(String[] args){
        System.out.println(PublicClass.squared(5)); // 25;
    }
}

So in this example above, we have a class named PublicClass declared as public, which means it is visible and can be accessed anywhere. Then inside this class, we have a static method named squared which takes one argument and returns its square number also marked as public. Then afterward, we want to test this method by creating a new class Main, this class contains the main method to execute this program, inside the main method, we call the square method of the PublicClass and give it an argument with a value of 5. Then again because this square method is public then we can access this method in another class. The result after compiling is 25.

protected

The name protected I think it is a bit misleading. From its sound, you might reckon that protected access is extremely restrictive —perhaps the next closest thing to private access. In fact, protected features are even more accessible than default features–which we will learn right after this section.

Unlike public access modifier, which is applied to almost everything, from interfaces, classes, methods, to variables, etc…Only variables, methods, and constructors may be declared as protected. While declared as protected,
the code is accessible in the same package and subclasses, protected variables and methods allow the class itself to access them, classes inside of the same package to access them, and subclasses of that class in a different package to access them. It’s quite ambiguous for now, let’s take an example to clarify this:

package Books;
public class Book {
    public int page = 324;
    public String description = "The unforgettable novel of a childhood in a sleepy Southern town and the crisis of conscience that rocked it.";
    public double rating = 4.27;

    protected void bookTitle() {
        System.out.println("To Kill A Mockingbird");
    }
}

class BookInfo extends Book {
    public static void main(String[] args){
        Book aBook = new Book();
        aBook.bookTitle(); // works fine, access bookTitle method through inheritence 
    }
}
class AnotherClass {
    public static void main(String[] args){
        Book anotherBook = new Book();
        anotherBook.bookTitle(); // works fine, because protected access modifier available anywhere within the same package, then we can directly call bookTitle() method through an instance.
    }
}

So now pretend we create another package named anotherpackage and import the Book class in the Books and we want to access the bookTitle() method in the Book class:

package anotherpackage;
import Books.Book; // import class Book in the Books package.
package anotherpackage;
public class AnotherClass{
      public void getTitle() {
          Book aBook = new Book();
          aBook.bookTitle(); // compiling error
      } 
}


This code segment above will throw an error because bookTitle() method in the Book class which is located in Books package has protected access, which means another package cannot involve this method unless we declare a class that inherits the Book class, like this:

package anotherpackage;
import Books.Book;
public class AnotherClass extends Book{
    public void getTitle() {
        Book anotherBook = new Book();
        anotherBook.bookTittle(); // no more error, works fine now!
    }
}

As you can see, if you want to access the code with protected access in a different package, we need to inherit the class which contains protected code we want by using the extends keyword followed by the parent class (we’ll cover more about inheritance and OOP concepts in some next articles.)

default

Default is the name of the access of classes, variables, and methods if you don’t specify an access modifier. This access modifier is special because it doesn’t have an associated keyword. And default access modifier is more restrictive than the protected modifier.

A variable or method declared without any access control modifier is available to any other class in the same package, anything outside that package will not be allowed to access it. For example:

package Aminal;
class Dog{
    public void bark() {
        System.out.println("Woof woof!");
    }
}

And now we have another package, named Akita and want to access to the Dog class in the Animal package:

package Akita;
import Animal.Dog;
public class Akita {
    public void doSomething() {
        Dog akita = new Dog(); // compiling error
    }
}

Because of class Dog has the default modifier, then classes in another package cannot access its code. However, it’s ok if the Akita class in the same package with the Dog class:

package Animal;
public class Akita {
    public void doSomething() {
        Dog akita = new Dog(); // no problem, works just fine.
    }
}

private

The most restrictive access modifier is private,  it can be applied for members only. Top-level class or interface never can be declared as private (except the inner class or interface can be declared as private but we will leave it on some more advanced articles). When a member is marked as private, it is only accessible from within the enclosing class. Nothing outside the class can access a private member. Private access is the ideal way to encapsulate the object itself and hides data from the outside world. For example:

class Dog {
    private int numOfTail = 1;
    private int numOfLegs = 4;
    private void bark() {
        System.out.println("Woof woof!");
    }
    
}
class Akita {
    public void getDogProperties() {
        Dog akita = new Dog();
        akita.bark(); // compiling error!
    }
}

We get a compiling error, even in the class Cat we use keyword extends to inherit Dog class properties, again, because everything inside Dog class is marked as private, which are just visible in their enclosing brackets and nothing else:

class Dog {
    private int numOfTail = 1;
    public int numOfLegs = 4;
    private void bark() {
        System.out.println("Woof woof!");
    }
    
}
class Akita extends Dog {
    public void getDogProperties() {
        Dog akita = new Dog();
        akita.bark(); // still compiling error!
    }
}

So we just can access the private variables, methods within their enclosing brackets, e.g the Dog class:

class Dog {
    private int numOfTail = 1;
    private int numOfLegs = 4;
    private void bark() {
        System.out.println("Woof woof!");
    }
    public static void main(String[] args){
        Dog dog = new Dog();
        System.out.println(dog.numOfLegs);
        System.out.println(dog.numOfTail);
        dog.bark();
    }
}

Output:

4
1
Woof woof!

For better understanding and to sum up, let us formulate a table of those 4 access modifiers:

Access ModifiersSame ClassSame PackageSubclassOther packages
publicYYYY
protectedYYYN
no access modifier (default)YYNN
privateYNNN
Previous Article
Next Article

Sign up for newsletter

* indicates required

Categories

Archives