在调用构造函数之后从main调用private-package方法

时间:2011-11-15 23:48:38

标签: java scjp

我正在学习SCJP,在学习的过程中我发现了一项看起来非常简单的练习,但我没有解决它,我不明白答案。该练习(摘自 OCP Java SE 6程序员实践考试,Bert Bates和Kathy Sierra),说明如下:

假设:

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

答案是:

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.

我的猜测是C,因为doStuff方法在MyPancake类中,所以main方法应该可以访问它。

重新考虑这个问题,当从静态上下文调用new时,如果doStuff是私有的,它可能无法访问私有方法。这是真的?我不确定这一点。

但无论如何,我仍然认为它可以访问package-private doStuff方法。 我想我错了,但我不知道为什么。

你能帮帮我吗?

谢谢!

3 个答案:

答案 0 :(得分:4)

很遗憾它没有给你一个关于为什么它将无法编译的答案 - 但幸运的是,当你有一个编译器时,你可以找到自己:

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

基本上,接口成员始终是公共的,因此您必须使用公共方法实现接口。这不是调用方法的问题 - 这是实现接口的问题。如果您取下“工具”部分,它将正常工作。

来自section 9.1.5 of the Java Language Specification

  

所有界面成员都是隐式公开的。根据§6.6的规则,如果接口也被声明为public或protected,则可以在声明接口的包外部访问它们。

答案 1 :(得分:2)

实施Pancake界面时。

您正在MyPancake类中提供doStuff()方法的实现

当您在MyPancake类中提供方法doStuff()的实现时,您还应该将其定义为public,因为接口中的所有成员变量和方法都是默认公用的。

因此,当您不提供访问修饰符时,会降低可见性。

答案 2 :(得分:2)

定义方法时

List<String> doStuff(List<String> s);

在Pancake界面中,你真正说的是:

public List<String> doStuff(List<String> s);

由于界面中的所有方法都是公共的,即使您没有明确表示它们也是如此。

现在,类MyPancake具有分配给doStuff(List s)方法的默认访问权限,因此不遵循接口,代码也无法编译。