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.

Advertisements