Access Modifiers: Scala & Java (II – Java Examples)

In our last post, we discussed about the access modifiers in Java and in Scala. As btilford noticed, there were no examples in that post, this post is supposed to cover the Java part.

In order to better understand how access modifiers works, we have to introduce the main classes. There will be one public class and one with the default access modifier.

Main Classes

package com.wordpress.j2eethoughts.accessModifiers.a; public class PublicFooClass { public int publicBar=0; protected int protectedBar=0; int defaultBar=0; private int privateBar=0; public void doStuff(){ PublicFooClass pubFoo = new PublicFooClass(); System.out.println(pubFoo.publicBar); System.out.println(pubFoo.protectedBar); System.out.println(pubFoo.defaultBar); System.out.println(pubFoo.privateBar); } public void doStuff2(){ System.out.println(publicBar); System.out.println(protectedBar); System.out.println(defaultBar); System.out.println(privateBar); } }
package com.wordpress.j2eethoughts.accessModifiers.a; class DefaultFooClass { public int publicBar=0; protected int protectedBar=0; int defaultBar=0; private int privateBar=0; public void doStuff(){ DefaultFooClass defFoo = new DefaultFooClass(); System.out.println(defFoo.publicBar); System.out.println(defFoo.protectedBar); System.out.println(defFoo.defaultBar); System.out.println(defFoo.privateBar); } public void doStuff2(){ System.out.println(publicBar); System.out.println(protectedBar); System.out.println(defaultBar); System.out.println(privateBar); } }

These two classes haven’t any compilation error. Now it’s time to make the compiler talk.

Basic Use

package com.wordpress.j2eethoughts.accessModifiers.a; public class TestClass { public static void test(){ //public class PublicFooClass pubFoo = new PublicFooClass(); System.out.println(pubFoo.publicBar); System.out.println(pubFoo.protectedBar); System.out.println(pubFoo.defaultBar); System.out.println(pubFoo.privateBar);//does not compile! //default class DefaultFooClass defFoo = new DefaultFooClass(); System.out.println(defFoo.publicBar); System.out.println(defFoo.protectedBar); System.out.println(defFoo.defaultBar); System.out.println(defFoo.privateBar);//does not compile! } }

Logically, the private fields are not visible for this TestClass. Protected, default, and public fields are visible because all classes lay in the same package.
If we move this class to another package, the compiler will complaint again.

package com.wordpress.j2eethoughts.accessModifiers.b; import com.wordpress.j2eethoughts.accessModifiers .a.PublicFooClass; public class TestClass { public static void main(){ //public class PublicFooClass pubFoo = new PublicFooClass(); System.out.println(pubFoo.publicBar); System.out.println(pubFoo.protectedBar);// does not compile! System.out.println(pubFoo.defaultBar);// does not compile! System.out.println(pubFoo.privateBar);// does not compile! //default class DefaultFooClass defFoo = new DefaultFooClass();// does not compile! System.out.println(defFoo.publicBar);// does not compile! System.out.println(defFoo.protectedBar);// does not compile! System.out.println(defFoo.defaultBar);// does not compile! System.out.println(defFoo.privateBar);// does not compile! } }

The DefaultFooClass is not visible at all for this class, because they don’t share the same package. The same rule applies for the protected and default fields of PublicFooClass.

Inheritance

There is another scope we haven’t analysed yet, the visibility in inheritance. We will extend the PublicFooClass in two different packages, discovering so the different ways that compiler complaints.
Firstly, we will implement a class extending PublicFooClass laying in the same package:

package com.wordpress.j2eethoughts.accessModifiers.a; public class SubPubFooClass extends PublicFooClass { public void doStuff(){ PublicFooClass pubFoo = new PublicFooClass(); System.out.println(pubFoo.publicBar); System.out.println(pubFoo.protectedBar); System.out.println(pubFoo.defaultBar); System.out.println(pubFoo.privateBar);// does not compile! } public void doStuff2(){ System.out.println(super.publicBar); System.out.println(super.protectedBar); System.out.println(super.defaultBar); System.out.println(super.privateBar);// does not compile! } }

As they share the same package, only private fields are not visible. So in this case, there is no difference (in visibility terms) between extending the class or not.
What will happen if the subclass lays in a different package?

package com.wordpress.j2eethoughts.accessModifiers.b; import com.wordpress.j2eethoughts.accessModifiers.a.PublicFooClass; public class SubPubFooClass extends PublicFooClass { public void doStuff(){ PublicFooClass pubFoo = new PublicFooClass(); System.out.println(pubFoo.publicBar); System.out.println(pubFoo.protectedBar);// does not compile! System.out.println(pubFoo.defaultBar);// does not compile! System.out.println(pubFoo.privateBar);// does not compile! } public void doStuff2(){ System.out.println(super.publicBar); System.out.println(super.protectedBar); System.out.println(super.defaultBar);// does not compile! System.out.println(super.privateBar);// does not compile! } }

In this case, we find some interesting compiler errors. In doStuff2 method we have the expected errors. Private fields are inaccessible by definition, and default fields are not visible because they don’t share the same package. Now, let’s focus on the first method. Why do the compiler find more errors in this case? Because the field is accessed from outside the object. In other words, the object that access this field, doesn’t own it, so it’s invisible in its eyes.

Inner Classes

In this last group of examples, we will focus on the Inner Classes and its visibility. The first thing we need is a class with some Inner Classes.

package com.wordpress.j2eethoughts.accessModifiers.a; public class FooClass { public int publicBar=0; protected int protectedBar=0; int defaultBar=0; private int privateBar=0; public void doStuff(){ System.out.println(publicBar); System.out.println(protectedBar); System.out.println(defaultBar); System.out.println(privateBar); PubBarClass pub = new PubBarClass(); ProBarClass pro = new ProBarClass(); DefBarClass def = new DefBarClass(); PriBarClass pri = new PriBarClass(); pri.doStuff(); } public ProBarClass getProBarClass(){ return new ProBarClass(); } public class PubBarClass{ public void doStuff(){ System.out.println(publicBar); System.out.println(protectedBar); System.out.println(defaultBar); System.out.println(privateBar); } } protected class ProBarClass{ public void doStuff(){ System.out.println(publicBar); System.out.println(protectedBar); System.out.println(defaultBar); System.out.println(privateBar); } } class DefBarClass{ public void doStuff(){ System.out.println(publicBar); System.out.println(protectedBar); System.out.println(defaultBar); System.out.println(privateBar); } } private class PriBarClass{ private void doStuff(){ System.out.println(publicBar); System.out.println(protectedBar); System.out.println(defaultBar); System.out.println(privateBar); } } }

We have one Inner Class for each type of modifier, this way, it will be easy to analyse what is possible and what is not. In this example, we can see that it’s possible to access outer class’ private fields from the inner class and vice-versa. Afterwards, we will test the visibility of the Inner Classes.

package com.wordpress.j2eethoughts.accessModifiers.a; import com.wordpress.j2eethoughts.accessModifiers .a.FooClass.DefBarClass; import com.wordpress.j2eethoughts.accessModifiers .a.FooClass.ProBarClass; import com.wordpress.j2eethoughts.accessModifiers .a.FooClass.PubBarClass; public class TestInner { public static void test(){ PubBarClass pub = new PubBarClass(); ProBarClass pro = new ProBarClass(); DefBarClass def = new DefBarClass(); PriBarClass pri = new PriBarClass();//does not compile! } }

As this class stands in the same package, all Inner Classes but the private are accessible.
If we move this class to another package we will get more errors.

package com.wordpress.j2eethoughts.accessModifiers.b; import com.wordpress.j2eethoughts.accessModifiers .a.FooClass.PubBarClass; public class TestInner { public static void test(){ PubBarClass pub = new PubBarClass(); FooClass foo = new FooClass(); ProBarClass pro = foo.getProBarClass(); //does not compile! ProBarClass pro2 = new ProBarClass();//does not compile! DefBarClass def = new DefBarClass();//does not compile! PriBarClass pri = new PriBarClass();//does not compile! } }

Only PubBarClass is visible, because this client doesn’t share neither package and ancestor with the Inner Classes. However, if we extend the ancestor class FooClass we will get different errors.

package com.wordpress.j2eethoughts.accessModifiers.b; import com.wordpress.j2eethoughts.accessModifiers.a.FooClass; public class TestInnerExtends extends FooClass { public void test(){ PubBarClass pub = new PubBarClass(); ProBarClass pro2 = getProBarClass(); ProBarClass pro = new ProBarClass();//does not compile! DefBarClass def = new DefBarClass();//does not compile! PriBarClass pri = new PriBarClass();//does not compile! } }

The instantiation of ProBarClass doesn’t compile because there is no user defined constructor, so the compiler adds automatically a protected one (the class is protected), thus it’s not visible for this client class because it doesn’t extend that ProBarClass. At this point, you would have deduced why the default and private classes are not accessible.

We hope all these examples could explain clearly what it can be done, and what can’t, with the access modifiers.

Access Modifiers: Scala & Java

In this post we will analyse the differences and the similarities between access modifiers in Scala and Java. Despite Scala is compatible with Java, there are some differences.

Java

In Java there are four types of access modifiers:

  • public: this is the less restrictive access modifier. Classes, methods, inner classes and fields can be declared public. Every class in every package can access the element declared public.
  • protected: methods, inner classes and fields can be declared protected. Only subclasses or classes in the same package can access the element declared protected.
  • default: classes, methods, inner classes and fields can be declared with no access modifier. Only classes in the same package can access the element declared with no modifier.
  • private: this is the most restrictive modifier. Methods, inner classes and fields can be declared private. Only the own class can access the elements declared private. Private methods or fields existing in an inner class can be accessed by the outer class.

Let’s make it more visual:

Modifier Class Package Subclass Every class
public Y Y Y Y
protected Y Y Y N
default Y Y N N
private Y N N N

Scala

In Scala there are three types of access modifiers (default that behaves like public, protected and private) but they can be augmented with qualifiers (only protected and private can). This qualification means that access is protected or private up to a scope.

First we will explain the unqualified access modifiers:

  • default: this is the less restrictive one, it behaves like public in Java. Classes, methods, inner classes and fields can be declared with no modifier. Every class in every package can access the element declared with no modifier.
  • protected: a member declared protected can be accessed only by its subclasses. This access modifier is more restrictive than its analogous in Java.
  • private: this is the most restrictive modifier. A member declared private can be accessed only by the owner class. This also applies for inner classes. In other words a private member is visible inside the own class and inside any deeper inner class. This rule only applies downwards, so a private member defined in an inner class can not be accessed by any outer class (this is possible in Java).

Let’s see the table:

Modifier Class Package Subclass Every class
default Y Y Y Y
protected Y N Y N
private Y N N N

Right now you could be wondering how to make a member visible for any class in the same package. The answer is scoped access modifiers. As we said, private and protected access modifiers can be qualified with a name of a package or class (scope). Generally scoped private and scoped protected access modifiers behave the same way, except under inheritance when declared on class members. The scope is defined between square brackets.

When the scope of protected or private is a package, the visibility is similar to package visibility in Java (default). Given a class X defined inside the package a.b.c, a member defined with protected[a] (or private[a]) is visible within package a. If you want the same behaviour than default visibility in Java, you must specify protected[c] (or private[c]).

When the scope is a class, the visibility is similar to private with some considerations. Given a class X with an inner class Y, a member in Y defined as protected[X] (or private[X]) behaves identically to private in Java. Otherwise, when defined as protected[Y] (or private[Y]) behaves identically to private in Scala.

There is yet another scope, this, that gives the most restrictive access modifier that exists. When a member of a class is defined as protected[this] (or private[this]), it is illegal to access this member outside the object. In other words, given private[this] var foo = 3, foo only can be accessed this way: this.foo.

Previously we said that scoped protected and private behave identically except under inheritance. The only difference is that scoped protected is less restrictive because, independently of the scope stated, a member defined with protected[something] is visible for any subclass, while when defined with private[something] is not.