2010-06-14 106 views
6

我是新来的Java(与C#的经验),如何从(静态)类中的类创建新的类实例?

这就是我想做的事:

public final class MyClass 
{ 
    public class MyRelatedClass 
    { 
     ... 
    } 
} 

public class OtherRandomClass 
{ 
    public void DoStuff() 
    { 
     MyRelatedClass data = new MyClass.MyRelatedClass(); 
    } 
} 

这使得这个错误在Eclipse:

No enclosing instance of type BitmapEffects is accessible. Must qualify the allocation with an enclosing instance of type BitmapEffects (e.g. x.new A() where x is an instance of BitmapEffects).

这是可能在C#中使用静态类,这里应该怎么做?

+0

可能重复[Java - 没有可以访问Foo类型的封闭实例](http://stackoverflow.com/questions/9560600/java-no-enclosing-instance-of-type- foo-is-accessible) – fabian 2016-03-03 23:46:05

回答

2

为了回应关于在一个文件中打包多个类的评论:与.NET不同,Java的大多数实现强制公共类类型的名称与声明类类型的文件的名称之间存在严格关联。不是一个硬性的要求,但没有使用相关性不被执行的系统。该JLS - 7.6 Top Level Type Declarations这样说:

When packages are stored in a file system (§7.2.1), the host system may choose to enforce the restriction that it is a compile-time error if a type is not found in a file under a name composed of the type name plus an extension (such as .java or .jav) if either of the following is true:

  • The type is referred to by code in other compilation units of the package in which the type is declared.
  • The type is declared public (and therefore is potentially accessible from code in other packages).

见这太问题:multiple class declarations in one file

如果您正在寻找创建一个命名空间附上相关的类,然后使用静态内部类是你所需要的。静态声明并不意味着一个instnace - 它们仍然可以被实例化 - static意味着它们可以被实例化而不需要引用封闭类。由于封闭类仅用于分组,而不是数据,因此您可以安全地将其设置为静态。为了更清楚地说明封闭类仅用于分组,您应该声明它为interface,以便它不能被实例化并且没有实现细节。

尽管个人,我会避免这样做 - 在Java中,包被用来强制执行命名空间。为此使用内部类很快变得麻烦。 (我已经尝试过了!)

+0

啊感谢信息:)。 (并感谢大家的帮助) – Mervin 2010-06-16 17:34:18

3

尝试将MyRelatedClass定义为静态。

编辑
更多关于这个问题
http://java.sun.com/docs/books/tutorial/java/javaOO/nested.html

+0

我不希望MyRelatedClass是静态的,我需要它的多个实例。 – Mervin 2010-06-14 17:32:20

+1

@Mervin请阅读链接中的描述(或马特的回答)。如果内部类是'静态',那并不意味着它只有一个实例。这意味着MyRelatedClass不会关联到任何特定的MyClass实例,并且将无法访问其(父类)实例成员。 – 2010-06-14 17:38:47

+0

@Mervin - 这不是什么静态手段在这种情况下。即使嵌套在MyClass中,它的行为仍然像顶级类一样。 – Robin 2010-06-14 17:40:27

19

你定义MyRelatedClass的样子,你需要有MyClass实例能够访问/实例化这个类。

通常在Java中,当MyRelatedClass的实例需要访问某个MyClass实例的某些字段(因此在编译器警告中引用“封闭实例”)时,可以使用此模式。

像这样的东西应该编译:

public void doStuff() { 
    MyClass mc = new MyClass(); 
    MyRelatedClass data = mc.new MyRelatedClass(); 
} 

但是,如果MyRelatedClass实例并不需要访问它的领域是包实例(MyClass的字段),那么你应该考虑定义MyRelatedClass作为一个静态类,这将允许您发布的原始代码进行编译。

在具有嵌套类(您已发布的信息)和静态嵌套类(一个classstatic class)不同的是,前者的嵌套类属于父类的例如,而后者没有这种关系 - 只有逻辑/名称空间关系。

+4

在隐式'this'以外的任何内容上创建(非静态)内部类使我生病。 – 2010-06-14 17:34:21

+0

以及我试图完成什么,我可以在C#中做: //[MapManagement.cs] 命名空间MapManagement { 公共静态类MapManager { ... } 公共类SpecialMapFile { ... } } 我想要2个类(非静态)在1文件,不知何故在Java中这是不允许的..错误:“公共类型*名称*需要定义在它自己的文件”所以这是我的解决方案,我想要1包,我想有相关的类分组在他们自己的文件 – Mervin 2010-06-14 17:47:05

+0

@Mervin如你所见,Java只允许每个文件一个公共顶级类。相关的类只能在相同的包中定义在不同的文件中。 – 2010-06-14 18:29:37

0

是的,非静态嵌套类可以访问外部类实例成员,因此必须为外部类的实例创建。所以,你有两个选择:

  1. 使嵌套类的静态作为默文暗示,或
  2. 作为错误信息建议使用外部类的一个实例创建它。

实际上,我很少创建一个内部类的实例,除了外部类的方法外,我很少使这样的类变为可变的 - 但这只是我自己。

+0

以及我试图完成我可以在c#中执行的操作:// [MapManagement.cs] namespace MapManagement {public static class MapManager {...} public class SpecialMapFile {...}}我想要2个类(non-静态)在1文件,不知何故在Java中,这是不允许的..错误:“公共类型名称需要在它自己的文件中定义”,所以这是我的解决方案,我想要1包,我想有相关类分组在自己的文件 - – Mervin 2010-06-14 17:56:26