Search code examples
javascjp

Calling a private-package method from main after calling the constructor


I am studying the SCJP, and while studying I have found an exercise that seemed very simple at first, but I failed resolving it, and I do not understand the answer. The exercise (taken from OCP Java SE 6 Programmer Practice Exams, Bert Bates and Kathy Sierra), says the following:

Given:

import java.util.*;
public class MyPancake implements Pancake {
  public static void main(String[] args) {
    List<String> x = new ArrayList<String>();
    x.add("3");x.add("7");x.add("5");
    List<String> y = new MyPancake().doStuff(x);
    y.add("1");
    System.out.println(x);
  }

  List<String> doStuff(List<String> z) {
    z.add("9");
    return z;
  }
}

interface Pancake {
  List<String> doStuff(List<String> s);
}


What is the most likely result?

A. [3, 7, 5]

B. [3, 7, 5, 9]

C. [3, 7, 5, 9, 1]

D. Compilation fails.

E. An exception is thrown at runtime

And the answer is:

D is correct. MyPancake.doStuff() must be marked public. If it is, then C would be
correct.

A, B, C, and E are incorrect based on the above.

My guess was C, because the doStuff method is inside the class MyPancake, so the main method should have access to it.

Reconsidering the question, when calling to new from the static context, it may not have access to the private methods, if doStuff were private. Is this true? I am not sure of this.

But anyway, I still think it would have access to the package-private doStuff method. I guess I am wrong, but I do not know why.

Could you help me?

Thank you!


Solution

  • It's very sad that it doesn't give you an answer as to why it would fail to compile - but fortunately when you've got a compiler, you can find out for yourself:

    Test.java:11: error: doStuff(List<String>) in MyPancake cannot implement doStuff
    (List<String>) in Pancake
      List<String> doStuff(List<String> z) {
                   ^
      attempting to assign weaker access privileges; was public
    2 errors
    

    Basically interface members are always public, so you have to implement interfaces with public methods. It's not a problem of calling the method - it's a problem in implementing the interface. If you took off the "implements" part it would work fine.

    From section 9.1.5 of the Java Language Specification:

    All interface members are implicitly public. They are accessible outside the package where the interface is declared if the interface is also declared public or protected, in accordance with the rules of §6.6.