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

时间:2022-11-25 08:04:47

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类型的实例(例如x)限定分配。新的A(),其中x是位图效果的实例)。

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

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

4 个解决方案

#1


2  

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 Declarations says 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:

当包存储在一个文件系统(§7.2.1),主机系统可以选择执行的限制,它是一种编译时错误如果没有找到下一个文件名称组成的类型名称加上一个扩展(例如. java或.jav)如果以下是正确的:

  • 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).
  • 类型被声明为public(因此可以从其他包中的代码访问它)。

See this SO question: multiple class declarations in one file

请参见SO问题:在一个文件中有多个类声明

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 static means 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.

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

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中,包被用于强制命名空间。为此使用内部类很快变得麻烦。(我已经试过!)

#2


19  

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

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

Typically in Java you use this pattern when an instance of MyRelatedClass needs to access some fields of a MyClass instance (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 MyRelatedClass instance does not need access to fields of it's enclosing instance (MyClass's fields) then you should consider defining MyRelatedClass as 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 class within a class) is that in the former, the nested class belongs to an instance of the parent class, while the latter has no such relationship - only a logical/namespace relationship.

嵌套类(您已经发布的内容)和静态嵌套类(类中的静态类)的不同之处在于,在前者中,嵌套类属于父类的一个实例,而后者没有这种关系——只有逻辑/名称空间关系。

#3


3  

Try defining MyRelatedClass as 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/javao/nested.html

#4


0  

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. 按照Mervin的建议,使嵌套类保持静态
  3. create it using an instance of the outer class as the error message suggests.
  4. 使用外部类的实例创建它,正如错误消息所建议的那样。

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.

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

#1


2  

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 Declarations says 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:

当包存储在一个文件系统(§7.2.1),主机系统可以选择执行的限制,它是一种编译时错误如果没有找到下一个文件名称组成的类型名称加上一个扩展(例如. java或.jav)如果以下是正确的:

  • 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).
  • 类型被声明为public(因此可以从其他包中的代码访问它)。

See this SO question: multiple class declarations in one file

请参见SO问题:在一个文件中有多个类声明

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 static means 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.

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

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中,包被用于强制命名空间。为此使用内部类很快变得麻烦。(我已经试过!)

#2


19  

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

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

Typically in Java you use this pattern when an instance of MyRelatedClass needs to access some fields of a MyClass instance (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 MyRelatedClass instance does not need access to fields of it's enclosing instance (MyClass's fields) then you should consider defining MyRelatedClass as 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 class within a class) is that in the former, the nested class belongs to an instance of the parent class, while the latter has no such relationship - only a logical/namespace relationship.

嵌套类(您已经发布的内容)和静态嵌套类(类中的静态类)的不同之处在于,在前者中,嵌套类属于父类的一个实例,而后者没有这种关系——只有逻辑/名称空间关系。

#3


3  

Try defining MyRelatedClass as 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/javao/nested.html

#4


0  

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. 按照Mervin的建议,使嵌套类保持静态
  3. create it using an instance of the outer class as the error message suggests.
  4. 使用外部类的实例创建它,正如错误消息所建议的那样。

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.

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