【问题标题】:How can I create a new class instance from a class within a (static) class?如何从(静态)类中的类创建新的类实例?
【发布时间】:2023-04-04 18:15:01
【问题描述】:

我是 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# 的静态类中是可能的,这里应该怎么做?

【问题讨论】:

标签: java


【解决方案1】:

尝试将MyRelatedClass 定义为静态。

编辑
更多主题
http://java.sun.com/docs/books/tutorial/java/javaOO/nested.html

【讨论】:

  • 我不希望 MyRelatedClass 是静态的,我需要它的多个实例。
  • @Mervin 请阅读链接中的描述(或马特的回答)。如果内部类是“静态的”,这并不意味着它只有一个实例。这意味着 MyRelatedClass 不会与 MyClass 的任何特定实例相关联,也无法访问其(父类)实例成员。
  • @Mervin - 这不是静态在这种情况下的含义。即使它嵌套在 MyClass 中,它也能有效地表现得像一个顶级类。
  • 好吧,我正在尝试完成我在 c# 中可以做的事情://[MapManagement.cs] namespace MapManagement { public static class MapManager { ... } public class SpecialMapFile { ... } }我想要 2 个类(非静态)在 1 个文件中,不知何故在 Java 中这是不允许的.. 错误:“公共类型名称需要在它自己的文件中定义”所以这是我的解决方案,我想要 1包,我想将相关的类分组在他们自己的文件中——
  • Java 非常希望每个文件都有一个公共类。强烈建议您坚持这一点,而不是试图绕过它。
【解决方案2】:

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

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

这样的东西应该可以编译:

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

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

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

【讨论】:

  • 在隐式 this 以外的任何东西上创建(非静态)内部类会让我生病。
  • 好吧,我正在尝试完成我在 c# 中可以做的事情://[MapManagement.cs] namespace MapManagement { public static class MapManager { ... } public class SpecialMapFile { ... } }我想要 2 个类(非静态)在 1 个文件中,不知何故在 Java 中这是不允许的.. 错误:“公共类型 name 需要在它自己的文件中定义”所以这是我的解决方案,我想要 1 个包,并且我希望将相关类分组在他们自己的文件中
  • @Mervin 正如您所见,Java 只允许每个文件有一个公共顶级类。相关的类可以在同一个包中的不同文件中定义。
【解决方案3】:

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

  1. 按照 Mervin 的建议将嵌套类设为静态,或者
  2. 如错误消息所示,使用外部类的实例创建它。

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

【讨论】:

  • 好吧,我正在尝试完成我在 c# 中可以做的事情://[MapManagement.cs] namespace MapManagement { public static class MapManager { ... } public class SpecialMapFile { ... } }我想要 2 个类(非静态)在 1 个文件中,不知何故在 Java 中这是不允许的.. 错误:“公共类型名称需要在它自己的文件中定义”所以这是我的解决方案,我想要 1包,我想将相关的类分组在他们自己的文件中——
【解决方案4】:

针对 cme​​ts 关于将多个类打包在一个文件中的回应:与 .NET 不同,java 的大多数实现都在公共类类型的名称和声明类类型的文件的名称之间强制执行严格的关联。不是硬性要求,但未使用未强制执行相关性的系统。 JLS - 7.6 Top Level Type Declarations 这么说:

当包存储在文件系统中(第 7.2.1 节)时,主机系统可能 选择强制执行该限制 如果一个类型是编译时错误 在名称下的文件中找不到 由类型名称加上一个 扩展名(例如 .java 或 .jav)如果 以下任一情况为真:

  • 该类型被其他编译单元中的代码引用 声明类型的包。
  • 该类型被声明为公共的(因此可能是可访问的 来自其他包中的代码)。

看到这个问题:multiple class declarations in one file

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

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

【讨论】:

  • 啊谢谢你的信息:)。 (感谢大家的帮助)
猜你喜欢
  • 2021-05-14
  • 2011-06-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多