java 如何从(静态)类中的类创建新的类实例?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3039306/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 00:03:56  来源:igfitidea点击:

How can I create a new class instance from a class within a (static) class?

java

提问by Mervin

I'm new to Java (have experience with C#),

我是 Java 新手(有 C# 经验),

this is what I want to do:

这就是我想要做的:

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

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

which gives this error in Eclipse:

这在 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).

无法访问 BitmapEffects 类型的封闭实例。必须使用 BitmapEffects 类型的封闭实例限定分配(例如 xnew A(),其中 x 是 BitmapEffects 的实例)。

This is possible in C# with static classes, how should it be done here?

这在带有静态类的 C# 中是可能的,这里应该如何完成?

采纳答案by mdma

In response to the comments about packaging multiple classes in one file: unlike .NET, most implementations of java enforce a strict correlation between the name of public class type and the name of the file the class type is declared in. It's not a hard requirement, but not used a system where the correlation is not enforced. The JLS - 7.6 Top Level Type Declarationssays this:

回应关于将多个类打包到一个文件中的评论:与 .NET 不同,java 的大多数实现都在公共类类型的名称和类类型声明所在的文件名称之间强制执行严格的相关性。这不是硬性要求,但未使用未强制执行相关性的系统。JLS - 7.6 顶级类型声明是这样说的:

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).

当包存储在文件系统中时(第 7.2.1 节),如果在由类型名称加如果以下任一情况为真,则为扩展名(例如 .java 或 .jav):

  • 该类型由声明该类型的包的其他编译单元中的代码引用。
  • 该类型被声明为 public(因此可以从其他包中的代码访问)。

See this SO question: multiple class declarations in one file

看到这个问题:多个类声明在一个文件中

If you are looking to create a namespace to enclose your related classes, then using static inner classes are what you need. The static declaration does not mean one instnace - they can still be instantiated - the staticmeans that they can be instantiated without needing a reference to the enclosing class. As the enclosing class is just for grouping, and not data, you are safe making it a static. To make it clearer that the enclosing class is just for grouping, you should declare it as an interface, so that it cannot be instantiated and has no implementation details.

如果您希望创建一个命名空间来包含您的相关类,那么使用静态内部类就是您所需要的。静态声明并不意味着一个实例——它们仍然可以被实例化——这static意味着它们可以被实例化而不需要对封闭类的引用。由于封闭类仅用于分组而不是数据,因此您可以安全地将其设为静态。为了更清楚地说明封闭类仅用于分组,您应该将其声明为 an interface,这样它就不能被实例化并且没有实现细节。

Although personally, I would refrain from doing this - in Java, packages are used to enforce a namespace. Using inner classes for this quickly becomes cumbersome. (I have tried it!)

虽然就我个人而言,我不会这样做 - 在 Java 中,包用于强制命名空间。为此使用内部类很快变得很麻烦。(我试过了!)

回答by matt b

The way you've defined MyRelatedClass, you need to have an instance ofMyClassto be able to access/instantiate this class.

按照您定义的方式MyRelatedClass,您需要有一个实例MyClass才能访问/实例化此类。

Typically in Java you use this pattern when an instance of MyRelatedClassneeds to access some fields of a MyClassinstance (hence the references to an "enclosing instance" in the compiler warning).

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

Something like this should compile:

这样的东西应该编译:

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

However, if a MyRelatedClassinstance does not need access to fields of it's enclosing instance (MyClass's fields) then you should consider defining MyRelatedClassas a static class, this will allow the original code you've posted to compile.

但是,如果MyRelatedClass实例不需要访问其封闭实例MyClass的字段(的字段),那么您应该考虑定义MyRelatedClass为静态类,这将允许您发布的原始代码进行编译。

The difference in having a nested class (what you've posted) and a static nested class (a static classwithin a class) is that in the former, the nested class belongs to an instance ofthe parent class, while the latter has no such relationship - only a logical/namespace relationship.

嵌套类(您发布的内容)和静态嵌套类( astatic class中的 a class)的区别在于,在前者中,嵌套类属于父类的一个实例,而后者没有这种关系-只有逻辑/命名空间关系。

回答by Nikita Rybak

Try defining MyRelatedClassas static.

尝试定义MyRelatedClass为静态。

edit
More on the subject
http://java.sun.com/docs/books/tutorial/java/javaOO/nested.html

编辑
有关该主题的更多信息
http://java.sun.com/docs/books/tutorial/java/javaOO/nested.html

回答by dsmith

Yes, non static nested classes have access to the outer classes instance members, and therefore must be created for an instance of the outer class. So you have two choices:

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

  1. make the nested class static as Mervin suggests, or
  2. create it using an instance of the outer class as the error message suggests.
  1. 按照 Mervin 的建议将嵌套类设为静态,或者
  2. 如错误消息所示,使用外部类的实例创建它。

In practice, I rarely create an instance of the inner class, except in methods of the outer class, and I rarely make such classes mutable -- but this is just me.

在实践中,我很少创建内部类的实例,除了在外部类的方法中,而且我很少使这些类可变——但这只是我。