我是Java的新手(有C#经验),
这就是我想要做的事情:
public final class MyClass
{
public class MyRelatedClass
{
...
}
}
public class OtherRandomClass
{
public void DoStuff()
{
MyRelatedClass data = new MyClass.MyRelatedClass();
}
}
在Eclipse中出现此错误:
无法访问BitmapEffects类型的封闭实例。必须使用BitmapEffects类型的封闭实例限定分配(例如x.new A(),其中x是BitmapEffects的实例)。
这在C#中可以使用静态类,这里应该怎么做?
答案 0 :(得分:19)
您定义MyRelatedClass
的方式,您需要有一个 MyClass
的实例才能访问/实例化此类。
通常在Java中,当MyRelatedClass
的实例需要访问MyClass
实例的某些字段(因此在编译器警告中引用“封闭实例”)时,您使用此模式。
这样的东西应该编译:
public void doStuff() {
MyClass mc = new MyClass();
MyRelatedClass data = mc.new MyRelatedClass();
}
但是,如果MyRelatedClass
实例不需要访问其封闭实例(MyClass
的字段)的字段,那么您应该考虑将MyRelatedClass
定义为静态类,这将是允许您发布的原始代码进行编译。
嵌套类(您发布的内容)和静态嵌套类(static class
中的class
)的区别在于前者,嵌套类属于< em>父类的实例,而后者没有这种关系 - 只有逻辑/命名空间关系。
答案 1 :(得分:4)
尝试将MyRelatedClass
定义为静态。
修改强>
更多关于这个主题的信息
http://java.sun.com/docs/books/tutorial/java/javaOO/nested.html
答案 2 :(得分:2)
回应关于在一个文件中打包多个类的注释:与.NET不同,java的大多数实现强制公共类类型的名称与声明类类型的文件的名称之间存在严格的关联。它不是硬性要求,但没有使用不强制执行相关性的系统。 JLS - 7.6 Top Level Type Declarations说明了这一点:
当包存储在文件系统(第7.2.1节)中时,主机系统可以 选择执行限制 如果是类型,则是编译时错误 在名称下的文件中找不到 由类型名称加上一个组成 扩展名(如.java或.jav)if 以下任何一种情况都属实:
- 该类型由其他编译单元中的代码引用 声明类型的包。
- 该类型被声明为公共类型(因此可以访问 来自其他软件包中的代码)。
请参阅此问题:multiple class declarations in one file
如果您希望创建一个名称空间来包含相关的类,那么您需要使用静态内部类。静态声明并不意味着一个实例 - 它们仍然可以被实例化 - static
意味着它们可以被实例化而无需引用封闭类。由于封闭类仅用于分组,而不是数据,因此您可以安全地将其设置为静态。为了更清楚地表明封闭类仅用于分组,您应该将其声明为interface
,以便它不能被实例化并且没有实现细节。
虽然就个人而言,我不会这样做 - 在Java中,包用于强制执行命名空间。使用内部类很快就变得很麻烦。 (我试过了!)
答案 3 :(得分:0)
是的,非静态嵌套类可以访问外部类实例成员,因此必须为外部类的实例创建。所以你有两个选择:
在实践中,我很少创建内部类的实例,除了外部类的方法,我很少使这些类可变 - 但这只是我。