Monday, August 11, 2014

Java's Access Modifiers

I recently purchased the Java SE 7 Programmer I practice test.  One of the questions asks: Which access modifier will permit access to class members only from subclasses and other classes in the same package? I picked the "no modifier" option for my answer, but the test says I should have picked protected.  So who's right?  Let's find out.
public
package Earth;

public class Earthling {
   public String name = "Bob";

   public void speak() {
      System.out.println("Hello.");
   }
}
Subclass, Same Package
package Earth;

public class Man extends Earthling {
   public Man() {
      System.out.println("name = " + name);
      speak();
   }

   public static void main(String[] args) {
      new Man();
   }
}
Result
name = Bob
Hello.
Non-Subclass, Same Package
package Earth;

public class Dog {
   public Dog() {
      Earthling earthling = new Earthling();
      System.out.println("earthling.name = " + earthling.name);
      earthling.speak();
   }

   public static void main(String[] args) {
      new Dog();
   }
}
Result
man.name = Bob
Hello.
Subclass, Different Package
package Mars;

import Earth.Earthling;

public class Explorer extends Earthling {
   public Explorer() {
      System.out.println("name = " + name);
      speak();
   }

   public static void main(String[] args) {
      new Explorer();
   }
}
Result
name = Bob
Hello.
Non-Subclass, Different Package
package Mars;

import Earth.Earthling;

public class Martian {
   public Martian() {
      Earthling earthling = new Earthling();
      System.out.println("earthling.name = " + earthling.name);
      earthling.speak();
   }

   public static void main(String[] args) {
      new Martian();
   }
}
Result
earthling.name = Bob
Hello.
protected
package Earth;

public class Earthling {
   protected String name = "Bob";

   protected void speak() {
      System.out.println("Hello.");
   }
}
Subclass, Same Package
Result
name = Bob
Hello.
Non-Subclass, Same Package
Result
earthling.name = Bob
Hello.
Subclass, Different Package
Result
name = Bob
Hello.
Non-Subclass, Different Package
Result
java: name has protected access in Earth.Earthling
java: speak() has protected access in Earth.Earthling
"no modifier" (ie. package)
package Earth;

public class Earthling {
   String name = "Bob";

   void speak() {
      System.out.println("Hello.");
   }
}
Subclass, Same Package
Result
name = Bob
Hello.
Non-Subclass, Same Package
Result
earthling.name = Bob
Hello.
Subclass, Different Package
Result
java: name is not public in Earth.Earthling;
  cannot be accessed from outside package
java: cannot find symbol
   symbol: method speak()
   location: class Mars.Explorer
Non-Subclass, Different Package
Result
java: name is not public in Earth.Earthling;
  cannot be accessed from outside package
java: speak() is not pubic in Earth.Earthling;
  cannot be accessed from outside package
private
package Earth;

public class Earthling {
   private String name = "Bob";

   private void speak() {
      System.out.println("Hello.");
   }
}
Subclass, Same Package
Result
java: name has private access in Earth.Earthling
java: cannot find symbol
   symbol: method speak()
   location: class Earth.Man
Non-Subclass, Same Package
Result
java: name has private access in Earth.Earthling
java: speak() has private access in Earth.Earthling
Subclass, Different Package
Result
java: name has private access in Earth.Earthling
java: cannot find symbol
   symbol: method speak()
   location: class Mars.Explorer
on-Subclass, Different Package
Result
java: name has private access in Earth.Earthling
java: speak() has private access in Earth.Earthling
Summary
The following table indicates when I was able to access Earthling's field and method.
public protected (no modifier) private
Subclass, Same Package x x x
Non-Subclass, Same Package x x x
Subclass, Different Package x x
Non-Subclass, Different Package x

The test was wrong. Specifying protected will allow a subclass in a different package the ability to access the class member, but the question asks about permission in the same package. So the correct answer should have been 'no modifier'.

2 comments:

  1. Great article! I may disagree with your parsing of the question, but you nailed the concept! You should ace the Java exam in no time!

    ReplyDelete
    Replies
    1. Okay, I see the error that I made. I read the question literally instead of critically, because if I had read it critically I would have asked myself why it says "subclasses and other classes" instead of just "classes". So in this case when it says subclasses its implied that they could be in any package.

      Which access modifier will permit access to class members only from classes in the same package and subclasses?

      Delete