2012-07-24 75 views
10

代码类声明中的成员接口隐式公开吗?

我有一个成员接口下面的类:

package com.example.withinterface; 

public class SomeClass { 

    interface SomeInterface { 

     void doSomething(); 
    } 
} 

而另一个类试图访问它:

package com.example.withinterface.main; 

import com.example.withinterface.SomeClass; 

public class Main { 

    public static void main(String[] argss) { 
     System.out.println(SomeClass.SomeInterface.class); 
    } 
} 

错误

在主我从javac得到以下错误:SomeInterface is not public in SomeClass; cannot be accessed from outside package。在Eclipse中:SomeInterface is not public in SomeClass; cannot be accessed from outside package

两者都编译为Java 7.如果我编写SomeInterface public,一切都会编译好。

但规格说

Java Language Specification for Java 7这样说:

甲构件接口是一个接口,其声明直接 封闭在另一个类或接口声明。

类声明中的成员接口隐式公开(§6.6) ,除非指定了访问修饰符。

Java Language Specification for Java 5似乎没有第二句话。

问题

所以不应SomeInterface被视为公众,不应该主要编译?

更新

至于建议的Ajay George这的确是an error in the Java Language Specification 7(感谢JamesB)。与此同时,规范被纠正,并删除了不正确的句子。 Last version in Archive.org with the incorrect sentence

+0

呵呵。除非另有说明,否则我一直认为一切都是包装保护。我想我学到了一些新东西。 – 2012-07-24 20:17:45

+1

我认为这是因为没有访问修饰符的memeber正在访问包。所以他们不能被其他软件包使用 – 2012-07-24 20:19:09

+0

@Desolator你看过这个问题吗?成员接口在默认情况下为**公共**。 – 2012-07-24 20:22:37

回答

2

我猜测规范是错误的。 这里是你的代码的javap输出。

E:\workspace>javap com\example\withinterface\SomeClass 
Warning: Binary file com\example\withinterface\SomeClass contains com.example.wi 
thinterface.SomeClass 
Compiled from "SomeClass.java" 
public class com.example.withinterface.SomeClass { 
    public com.example.withinterface.SomeClass(); 
} 

E:\workspace>javap com\example\withinterface\SomeClass$SomeInterface 
Warning: Binary file com\example\withinterface\SomeClass$SomeInterface contains 
com.example.withinterface.SomeClass$SomeInterface 
Compiled from "SomeClass.java" 
interface com.example.withinterface.SomeClass$SomeInterface { 
    public abstract void doSomething(); 
} 

我将接口改为public,然后重新编译它。

E:\workspace>javap com\example\withinterface\SomeClass 
Warning: Binary file com\example\withinterface\SomeClass contains com.example.wi 
thinterface.SomeClass 
Compiled from "SomeClass.java" 
public class com.example.withinterface.SomeClass { 
    public com.example.withinterface.SomeClass(); 
} 

E:\workspace>javap com\example\withinterface\SomeClass$SomeInterface 
Warning: Binary file com\example\withinterface\SomeClass$SomeInterface contains 
com.example.withinterface.SomeClass$SomeInterface 
Compiled from "SomeClass.java" 
public interface com.example.withinterface.SomeClass$SomeInterface { 
    public abstract void doSomething(); 
} 

注意内部类的区别。

+2

我同意。 JLS显然是错误的。使用Java 7 JDK,代码仅在成员接口被**明确声明为public时进行编译。 – JamesB 2012-07-24 21:37:53

+0

@JamesB不,规范**不能**根据定义是错误的。实施出了什么问题。 JLS不是描述性的,而是**规定性的**。 – 2012-07-25 07:54:19

+0

@MarkoTopolnik它确实看起来像一个错字:*“**类声明中的成员接口是隐式公开的”*应该可能是*“**接口**声明中的成员接口是隐式公开的”*。这在上一句话的背景下是有意义的:*“封装在另一个类或接口声明中”*。 – assylias 2012-07-25 08:14:20