何时在Java中使用内部类作为辅助类。

时间:2022-09-25 12:23:43

If I have for example a class along with a helper class to do some of its functionality, does it make sense to make it as an inner class.

如果我有一个类和一个助手类来完成它的一些功能,那么将它作为一个内部类是否有意义呢?

    public class Foo {
       private FooHelper helper;

       // constructor & any other logic

       public void doSomeThing() {
         helper.do();
       }
    }

    public class FooHelper {
        public void do() {
         // code
        }
    }

In the above case does it make sense to make the FooHelper as an inner class ? Apology if this sound stupid but I am little confused about the use cases.

在上面的例子中,将FooHelper作为一个内部类是否有意义?如果这听起来很愚蠢的话,我道歉,但是我对用例有点困惑。

11 个解决方案

#1


41  

Yes, it makes perfect sense to make it an inner class. If no other classes need it, make it private. If it doesn't require exclusive access to the members of the outer class, make it a static nested class because then it will require less memory space.

是的,让它成为一个内部类是很有意义的。如果没有其他类需要它,请将其设置为私有。如果它不需要对外部类的成员进行独占访问,则使它成为一个静态嵌套类,因为这样就需要较少的内存空间。

Check out the recommendation from the official tutorial -

请查阅官方指南的推荐信。

Use a non-static nested class (or inner class) if you require access to an enclosing instance's non-public fields and methods. Use a static nested class if you don't require this access.

如果需要访问封闭实例的非公共字段和方法,请使用非静态嵌套类(或内部类)。如果不需要此访问,请使用静态嵌套类。

#2


10  

If you think that FooHelper will not at all be useful for other classes than Foo, then it makes sense to make it as private inner class of Foo. One example of this kind of design can be found in HashMap where it defines a private inner class KeySet

如果您认为FooHelper对其他类没有任何用处,那么将它作为Foo的私有内部类是有意义的。这种设计的一个例子可以在HashMap中找到,它定义了一个私有的内部类KeySet。

Otherwise having it as a private instance looks good.

否则,将其作为私有实例看起来很好。

#3


6  

From JAVA SE Docs

从JAVA SE文档

Why Use Nested Classes?

为什么使用嵌套类?

It is a way of logically grouping classes that are only used in one place: If a class is useful to only one other class, then it is logical to embed it in that class and keep the two together. Nesting such "helper classes" makes their package more streamlined.

它是一种逻辑分组的方法,只在一个地方使用:如果一个类只对另一个类有用,那么将它嵌入到那个类中并将二者保持在一起是合理的。嵌套这样的“助手类”使它们的包更具流线型。

It increases encapsulation: Consider two top-level classes, A and B, where B needs access to members of A that would otherwise be declared private. By hiding class B within class A, A's members can be declared private and B can access them. In addition, B itself can be hidden from the outside world.

它增加了封装:考虑两个*类,A和B,其中B需要访问被声明为私有的A的成员。通过在类A中隐藏B类,A的成员可以被声明为私有,B可以访问它们。此外,B本身也可以隐藏在外面的世界。

So Yes, it makes sense to use FooHelper as an inner class.

所以,使用FooHelper作为内部类是有意义的。

#4


4  

Here are some uses of inner classes.

下面是一些内部类的用法。

  • Inner classes are used to get functionality which can get an object better than method.
  • 内部类用于获得比方法更好的功能。
  • They can be used in the case when a set of multiple operations are required and chances of reusability are good inside the class and they will not be accessed but methods outside the outer class.
  • 当需要多个操作时,可以使用它们,并且在类中重用性很好,并且它们不会被访问,而是在外部类之外的方法。
  • Inner classes are made to achieve multiple inheritance also.
  • 内部类也被用来实现多重继承。
  • Inner classes are used when they are useful in class context.
  • 当它们在类上下文中有用时,就使用内部类。
  • They are used to separate logic inside classes.
  • 它们被用来分隔类中的逻辑。

So if you have some requirement matching above points than inner classes can be used. It is always better to make inner class private to prevent access from other classes. In your case use of inner classes is helpful to make code readable and separate logic in the outer class.

因此,如果您有一些需求匹配上面的点,而不是内部类可以使用。让内部类私有来防止其他类的访问总是更好的。在您的案例中,使用内部类有助于使代码在外部类中具有可读性和独立的逻辑。

#5


1  

Inner classes make sense when they are tiny and don't need names. Listeners in GUIs are classic examples where they make sense.

内部类在很小的时候是有意义的,并且不需要名称。GUIs的听众是典型的有意义的例子。

If the class is big and important, it should be named and placed in a separate file.

如果这个类很大并且很重要,它应该被命名并放在一个单独的文件中。

The listener classes in normal GUI examples do one tiny thing, usually just dispatch to some other function to do real work.

在正常的GUI示例中,侦听器类只执行一个小的任务,通常只是分派到其他函数来执行实际的工作。

I also often use static nested classes (which are technically not inner classes) for classes which are only used in the context of another class - Map.Entry is a good example of this. It's only used in conjunction with a Map, so having the definition of Entry be a part of the Map interface makes organizational sense.

我还经常使用静态嵌套类(技术上不是内部类),这些类只在另一个类- Map的上下文中使用。条目就是一个很好的例子。它只与映射一起使用,因此,具有条目的定义是映射接口的一部分,这是组织意义的一部分。

I don't generally have much use for other types of nested classes, like nonstatic member classes and local classes. But they do occasionally come in useful. For a good example of a legitimate use for member classes, see the source code for LinkedList.ListItr. This is a private inner class whose purpose is to provide an implementation of ListIterator for a LinkedList. To do this, it's useful to have access to the private data inside the LinkedList. To achieve this using only top-level classes, it would have been necessary to expose more public methods in LinkedList to allow the ListIterator to get at the underlying implementation of the LinkedList. Instead, using an inner class allows LinkedList to keep its implementation private, as it should be.

对于其他类型的嵌套类(如非静态成员类和本地类),我通常不太常用。但它们偶尔也会有用。对于成员类合法使用的一个很好的例子,请参见LinkedList.ListItr的源代码。这是一个私有内部类,其目的是为LinkedList提供一个ListIterator的实现。为此,可以访问LinkedList内的私有数据。要使用*类来实现这一点,需要在LinkedList中公开更多的公共方法,以便允许ListIterator访问LinkedList的底层实现。相反,使用内部类允许LinkedList保持其实现的私有性,这是应该的。

#6


1  

Yes, the advantage of using inner class is it can access members of outer class.In your case , if you think your FooHelper is not to be used by any other class,you can make it a inner class.

是的,使用内部类的优点是它可以访问外部类的成员。在您的情况中,如果您认为您的FooHelper不被其他类使用,您可以将它作为一个内部类。

To check out the utility of inner class, go through the examples of AWT. Anonymous inner classes are widely used in event handlers.

要查看内部类的实用程序,请查看AWT的示例。匿名内部类在事件处理程序中被广泛使用。

#7


0  

What is Foo's scope? When Foo is domain model class with it's own lifecycle and helper is common service, seems like mixing of two objects with very different scope/lifecycle.

Foo的范围是什么?当Foo是域模型类时,它自己的生命周期和帮助器是公共服务,这看起来像是两个对象的混合,它们的范围和生命周期非常不同。

Typically domain entity has it's own lifecycle from creation, persistence to it's GC. On the other hand, helper or service is either static or better dynamic with lifecycle equals to the whole app, e.g. spring bean.

典型的域实体有自己的生命周期,从创建到它的GC。另一方面,助手或服务要么是静态的,要么是动态的,生命周期等于整个应用程序,比如spring bean。

Once your domain entity would contain reference of a service it can bring you serious problems. E.g. every call to repository's Get needs to inject reference of this service into domain entity. I'd recommend to avoid this pattern.

一旦域实体包含了服务的引用,它就会给您带来严重的问题。对存储库的每个调用都需要将该服务的引用注入域实体。我建议避免这种模式。

It's not apparent for me who will make instance of Helper for you.

对我来说,谁会为你做帮助者,这并不明显。

#8


0  

Hild, Yes, it makes sense to use an inner class in many cases.

Hild,是的,在很多情况下使用内部类是有意义的。

Think of it this way - the inner class will live and die with the outer class, so any functionality that is specifically needed for the outer class can be added to the inner class. Popular examples are - Listeners in most cases - Types of KeyListeners, MouseListeners, eventListeners.

这样想——内部类将与外部类一起生存和死亡,因此,外部类所特别需要的任何功能都可以添加到内部类中。流行的例子是——大多数情况下的侦听器——类型的键监听器、mouselistener、eventlistener。

Classes in Java allow you to have specific functionality, but sometimes you may need to have a separate specialized functionality but it also needs to be intimately tied to the class you're designing.

Java类允许您拥有特定的功能,但有时您可能需要单独的专门功能,但它也需要与您正在设计的类紧密相关。

There can be four types of inner classes. A simple google search can help you to find out more about them.

可以有四种类型的内部类。一个简单的谷歌搜索可以帮助你找到更多关于他们的信息。

#9


0  

Nested Classes,enable you to logically group classes that are only used in one place, increase the use of encapsulation, and create more readable and maintainable code. Local classes, anonymous classes.

嵌套类,使您能够在逻辑上对仅在一个地方使用的类进行分组,增加了对封装的使用,并创建了更易于阅读和可维护的代码。本地类,匿名类。

http://docs.oracle.com/javase/tutorial/java/javaOO/whentouse.html

http://docs.oracle.com/javase/tutorial/java/javaOO/whentouse.html

#10


0  

There are two additional types of inner classes. You can declare an inner class within the body of a method. These classes are known as local classes. You can also declare an inner class within the body of a method without naming the class. These classes are known as anonymous classes.

还有另外两种类型的内部类。您可以在方法的主体内声明一个内部类。这些类称为本地类。您还可以在方法的主体内声明一个内部类,而不指定该类。这些类被称为匿名类。

Local class: Use it if you need to create more than one instance of a class, access its constructor, or introduce a new, named type (because, for example, you need to invoke additional methods later).

本地类:如果您需要创建一个类的多个实例,访问它的构造函数,或者引入一个新的命名类型(因为,例如,您需要在以后调用其他方法),那么就使用它。

Anonymous class: Use it if you need to declare fields or additional methods.

匿名类:如果需要声明字段或其他方法,请使用它。

#11


0  

When to use inner classes?

何时使用内部类?

  1. Inner class does not need any additional or separate file to place.
  2. 内部类不需要任何附加或单独的文件。
  3. Inner classes are comparatively small and tightly coupled with the “parent” class or “outer” class. Avoids lot of helper classes and fits to explain the OOD principle of containment.
  4. 内部类相对较小,与“父类”类或“外部”类紧密耦合。避免了许多帮助类,并适合解释容器的OOD原则。
  5. All the code in the same file increases readability and increases performance (like online code). Their importance is growing in the coding and treated as a good practice.
  6. 同一文件中的所有代码都增加了可读性,并提高了性能(如在线代码)。它们的重要性在编码中不断增长,并被视为一种良好的实践。
  7. Anonymous inner classes are very useful when you want to define callbacks on the fly.
  8. 当您想要定义回调函数时,匿名内部类非常有用。
  9. An object of an inner class can access the implementation of the object that created it- INCLUDING private data.
  10. 内部类的对象可以访问创建它的对象的实现——包括私有数据。

#1


41  

Yes, it makes perfect sense to make it an inner class. If no other classes need it, make it private. If it doesn't require exclusive access to the members of the outer class, make it a static nested class because then it will require less memory space.

是的,让它成为一个内部类是很有意义的。如果没有其他类需要它,请将其设置为私有。如果它不需要对外部类的成员进行独占访问,则使它成为一个静态嵌套类,因为这样就需要较少的内存空间。

Check out the recommendation from the official tutorial -

请查阅官方指南的推荐信。

Use a non-static nested class (or inner class) if you require access to an enclosing instance's non-public fields and methods. Use a static nested class if you don't require this access.

如果需要访问封闭实例的非公共字段和方法,请使用非静态嵌套类(或内部类)。如果不需要此访问,请使用静态嵌套类。

#2


10  

If you think that FooHelper will not at all be useful for other classes than Foo, then it makes sense to make it as private inner class of Foo. One example of this kind of design can be found in HashMap where it defines a private inner class KeySet

如果您认为FooHelper对其他类没有任何用处,那么将它作为Foo的私有内部类是有意义的。这种设计的一个例子可以在HashMap中找到,它定义了一个私有的内部类KeySet。

Otherwise having it as a private instance looks good.

否则,将其作为私有实例看起来很好。

#3


6  

From JAVA SE Docs

从JAVA SE文档

Why Use Nested Classes?

为什么使用嵌套类?

It is a way of logically grouping classes that are only used in one place: If a class is useful to only one other class, then it is logical to embed it in that class and keep the two together. Nesting such "helper classes" makes their package more streamlined.

它是一种逻辑分组的方法,只在一个地方使用:如果一个类只对另一个类有用,那么将它嵌入到那个类中并将二者保持在一起是合理的。嵌套这样的“助手类”使它们的包更具流线型。

It increases encapsulation: Consider two top-level classes, A and B, where B needs access to members of A that would otherwise be declared private. By hiding class B within class A, A's members can be declared private and B can access them. In addition, B itself can be hidden from the outside world.

它增加了封装:考虑两个*类,A和B,其中B需要访问被声明为私有的A的成员。通过在类A中隐藏B类,A的成员可以被声明为私有,B可以访问它们。此外,B本身也可以隐藏在外面的世界。

So Yes, it makes sense to use FooHelper as an inner class.

所以,使用FooHelper作为内部类是有意义的。

#4


4  

Here are some uses of inner classes.

下面是一些内部类的用法。

  • Inner classes are used to get functionality which can get an object better than method.
  • 内部类用于获得比方法更好的功能。
  • They can be used in the case when a set of multiple operations are required and chances of reusability are good inside the class and they will not be accessed but methods outside the outer class.
  • 当需要多个操作时,可以使用它们,并且在类中重用性很好,并且它们不会被访问,而是在外部类之外的方法。
  • Inner classes are made to achieve multiple inheritance also.
  • 内部类也被用来实现多重继承。
  • Inner classes are used when they are useful in class context.
  • 当它们在类上下文中有用时,就使用内部类。
  • They are used to separate logic inside classes.
  • 它们被用来分隔类中的逻辑。

So if you have some requirement matching above points than inner classes can be used. It is always better to make inner class private to prevent access from other classes. In your case use of inner classes is helpful to make code readable and separate logic in the outer class.

因此,如果您有一些需求匹配上面的点,而不是内部类可以使用。让内部类私有来防止其他类的访问总是更好的。在您的案例中,使用内部类有助于使代码在外部类中具有可读性和独立的逻辑。

#5


1  

Inner classes make sense when they are tiny and don't need names. Listeners in GUIs are classic examples where they make sense.

内部类在很小的时候是有意义的,并且不需要名称。GUIs的听众是典型的有意义的例子。

If the class is big and important, it should be named and placed in a separate file.

如果这个类很大并且很重要,它应该被命名并放在一个单独的文件中。

The listener classes in normal GUI examples do one tiny thing, usually just dispatch to some other function to do real work.

在正常的GUI示例中,侦听器类只执行一个小的任务,通常只是分派到其他函数来执行实际的工作。

I also often use static nested classes (which are technically not inner classes) for classes which are only used in the context of another class - Map.Entry is a good example of this. It's only used in conjunction with a Map, so having the definition of Entry be a part of the Map interface makes organizational sense.

我还经常使用静态嵌套类(技术上不是内部类),这些类只在另一个类- Map的上下文中使用。条目就是一个很好的例子。它只与映射一起使用,因此,具有条目的定义是映射接口的一部分,这是组织意义的一部分。

I don't generally have much use for other types of nested classes, like nonstatic member classes and local classes. But they do occasionally come in useful. For a good example of a legitimate use for member classes, see the source code for LinkedList.ListItr. This is a private inner class whose purpose is to provide an implementation of ListIterator for a LinkedList. To do this, it's useful to have access to the private data inside the LinkedList. To achieve this using only top-level classes, it would have been necessary to expose more public methods in LinkedList to allow the ListIterator to get at the underlying implementation of the LinkedList. Instead, using an inner class allows LinkedList to keep its implementation private, as it should be.

对于其他类型的嵌套类(如非静态成员类和本地类),我通常不太常用。但它们偶尔也会有用。对于成员类合法使用的一个很好的例子,请参见LinkedList.ListItr的源代码。这是一个私有内部类,其目的是为LinkedList提供一个ListIterator的实现。为此,可以访问LinkedList内的私有数据。要使用*类来实现这一点,需要在LinkedList中公开更多的公共方法,以便允许ListIterator访问LinkedList的底层实现。相反,使用内部类允许LinkedList保持其实现的私有性,这是应该的。

#6


1  

Yes, the advantage of using inner class is it can access members of outer class.In your case , if you think your FooHelper is not to be used by any other class,you can make it a inner class.

是的,使用内部类的优点是它可以访问外部类的成员。在您的情况中,如果您认为您的FooHelper不被其他类使用,您可以将它作为一个内部类。

To check out the utility of inner class, go through the examples of AWT. Anonymous inner classes are widely used in event handlers.

要查看内部类的实用程序,请查看AWT的示例。匿名内部类在事件处理程序中被广泛使用。

#7


0  

What is Foo's scope? When Foo is domain model class with it's own lifecycle and helper is common service, seems like mixing of two objects with very different scope/lifecycle.

Foo的范围是什么?当Foo是域模型类时,它自己的生命周期和帮助器是公共服务,这看起来像是两个对象的混合,它们的范围和生命周期非常不同。

Typically domain entity has it's own lifecycle from creation, persistence to it's GC. On the other hand, helper or service is either static or better dynamic with lifecycle equals to the whole app, e.g. spring bean.

典型的域实体有自己的生命周期,从创建到它的GC。另一方面,助手或服务要么是静态的,要么是动态的,生命周期等于整个应用程序,比如spring bean。

Once your domain entity would contain reference of a service it can bring you serious problems. E.g. every call to repository's Get needs to inject reference of this service into domain entity. I'd recommend to avoid this pattern.

一旦域实体包含了服务的引用,它就会给您带来严重的问题。对存储库的每个调用都需要将该服务的引用注入域实体。我建议避免这种模式。

It's not apparent for me who will make instance of Helper for you.

对我来说,谁会为你做帮助者,这并不明显。

#8


0  

Hild, Yes, it makes sense to use an inner class in many cases.

Hild,是的,在很多情况下使用内部类是有意义的。

Think of it this way - the inner class will live and die with the outer class, so any functionality that is specifically needed for the outer class can be added to the inner class. Popular examples are - Listeners in most cases - Types of KeyListeners, MouseListeners, eventListeners.

这样想——内部类将与外部类一起生存和死亡,因此,外部类所特别需要的任何功能都可以添加到内部类中。流行的例子是——大多数情况下的侦听器——类型的键监听器、mouselistener、eventlistener。

Classes in Java allow you to have specific functionality, but sometimes you may need to have a separate specialized functionality but it also needs to be intimately tied to the class you're designing.

Java类允许您拥有特定的功能,但有时您可能需要单独的专门功能,但它也需要与您正在设计的类紧密相关。

There can be four types of inner classes. A simple google search can help you to find out more about them.

可以有四种类型的内部类。一个简单的谷歌搜索可以帮助你找到更多关于他们的信息。

#9


0  

Nested Classes,enable you to logically group classes that are only used in one place, increase the use of encapsulation, and create more readable and maintainable code. Local classes, anonymous classes.

嵌套类,使您能够在逻辑上对仅在一个地方使用的类进行分组,增加了对封装的使用,并创建了更易于阅读和可维护的代码。本地类,匿名类。

http://docs.oracle.com/javase/tutorial/java/javaOO/whentouse.html

http://docs.oracle.com/javase/tutorial/java/javaOO/whentouse.html

#10


0  

There are two additional types of inner classes. You can declare an inner class within the body of a method. These classes are known as local classes. You can also declare an inner class within the body of a method without naming the class. These classes are known as anonymous classes.

还有另外两种类型的内部类。您可以在方法的主体内声明一个内部类。这些类称为本地类。您还可以在方法的主体内声明一个内部类,而不指定该类。这些类被称为匿名类。

Local class: Use it if you need to create more than one instance of a class, access its constructor, or introduce a new, named type (because, for example, you need to invoke additional methods later).

本地类:如果您需要创建一个类的多个实例,访问它的构造函数,或者引入一个新的命名类型(因为,例如,您需要在以后调用其他方法),那么就使用它。

Anonymous class: Use it if you need to declare fields or additional methods.

匿名类:如果需要声明字段或其他方法,请使用它。

#11


0  

When to use inner classes?

何时使用内部类?

  1. Inner class does not need any additional or separate file to place.
  2. 内部类不需要任何附加或单独的文件。
  3. Inner classes are comparatively small and tightly coupled with the “parent” class or “outer” class. Avoids lot of helper classes and fits to explain the OOD principle of containment.
  4. 内部类相对较小,与“父类”类或“外部”类紧密耦合。避免了许多帮助类,并适合解释容器的OOD原则。
  5. All the code in the same file increases readability and increases performance (like online code). Their importance is growing in the coding and treated as a good practice.
  6. 同一文件中的所有代码都增加了可读性,并提高了性能(如在线代码)。它们的重要性在编码中不断增长,并被视为一种良好的实践。
  7. Anonymous inner classes are very useful when you want to define callbacks on the fly.
  8. 当您想要定义回调函数时,匿名内部类非常有用。
  9. An object of an inner class can access the implementation of the object that created it- INCLUDING private data.
  10. 内部类的对象可以访问创建它的对象的实现——包括私有数据。