Java 匿名与命名内部类?- 最佳实践?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/714602/
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-08-11 18:39:37  来源:igfitidea点击:

Anonymous vs named inner classes? - best practices?

javaoopclassinheritanceanonymous-class

提问by Joe Attardi

I have a class, let's call it LineGraph, that renders a line graph. I need to subclass it, but the derived class is only used in one place and is coupled to the class that uses it. So I am using an inner class.

我有一个类,我们称之为 LineGraph,它呈现一个折线图。我需要对它进行子类化,但是派生类只在一个地方使用,并且与使用它的类耦合。所以我使用的是内部类。

I see two ways to do this:

我看到有两种方法可以做到这一点:

Anonymous inner class

匿名内部类

public class Gui {
    LineGraph graph = new LineGraph() {
        // extra functionality here.
    };
}

Named inner class

命名内部类

public class Gui {
    MyLineGraph graph = new MyLineGraph();

    private class MyLineGraph extends LineGraph {
        // extra functionality here.
    }
}

I am not a fan of anonymous inner classes, because frankly I just think it looks really ugly. But in the case of a subclass that's only used in one place, is a named inner class overkill? What is the accepted practice?

我不喜欢匿名内部类,因为坦率地说,我只是觉得它看起来很丑。但是对于只在一个地方使用的子类,命名内部类是否有点过分?什么是公认的做法?

回答by Jon Skeet

Why do you need to subclass it? If it's just to override an existing virtual method, I think an anonymous inner class is okay. If you're adding extra functionality, I'd use a named class. I'd make it a nested class though (i.e. with the staticmodifier) - I find them easier to reason about :)

为什么需要对它进行子类化?如果只是为了覆盖现有的虚方法,我认为匿名内部类是可以的。如果您要添加额外的功能,我会使用命名类。不过,我会将static其设为嵌套类(即使用修饰符) - 我发现它们更容易推理:)

回答by Mike Pone

I think what you've done makes perfect sense in this case and either way you look at it, I think you are really splitting hairs with this particular issue. They are both so similar and either will work.

我认为你所做的在这种情况下是完全合理的,无论你怎么看,我认为你真的对这个特定问题感到不满。它们都非常相似,并且都可以工作。

回答by Dan Lew

One advantage of anonymous inner classes is that no one can ever use it anywhere else, whereas a named inner class can be used (if only by the class that created it if made private). It's a small distinction, but it does mean that you can protect an inner class from being accidentally used elsewhere.

匿名内部类的一个优点是没有人可以在其他任何地方使用它,而命名内部类可以使用(如果只有创建它的类私有)。这是一个很小的区别,但这确实意味着您可以保护内部类免于在其他地方意外使用。

Also, using the anonymous inner class gives anyone reading your code a head's up - "this class is being used just here and nowhere else." If you see a named inner class, someone might think it'd be used in multiple places in the class.

此外,使用匿名内部类可以让任何阅读您代码的人抬头——“这个类只在这里使用,在其他地方没有使用。” 如果您看到一个命名的内部类,有人可能会认为它会在类中的多个地方使用。

They are very similar, so neither point is a game-changer. I just think it helps for clarity if you use anonymous inner classes for one-offs, and named inner classes when it's used multiple times within the class.

它们非常相似,所以这两点都不会改变游戏规则。我只是认为,如果您一次性使用匿名内部类,并在类中多次使用时使用命名内部类,这有助于清晰。

回答by Andrei Vajna II

I think this is a matter of taste. I prefer to use anonymous classes for Functors. But in your case, I'd use an inner class, since I think you'll be packing more than just a few lines of code in there, perhaps more than just a method. And it would emphasise the fact that it's adding functionality to the superclass, by putting it inside the class, rather than hidden somewhere in a method. Plus, who knows, maybe someday you might need the subclass else where. This, of course, depends on how much you know about how your software will evolve. Other than that, just flip a coin. :)

我认为这是一个品味问题。我更喜欢对Functors使用匿名类。但是在您的情况下,我会使用内部类,因为我认为您将在其中打包的不仅仅是几行代码,也许不仅仅是一个方法。它会强调这样一个事实,即通过将它放在类中而不是隐藏在方法中的某个地方,它正在向超类添加功能。另外,谁知道呢,也许有一天你可能需要其他地方的子类。当然,这取决于您对软件将如何发展的了解程度。除此之外,只需抛硬币。:)

回答by Kapsh

Anonymous inner classes are hard to debug in Eclipse (thats what I use). You will not be able to look at variable values/inject values by simply right clicking.

匿名内部类很难在 Eclipse 中调试(这就是我使用的)。只需右键单击,您将无法查看变量值/注入值。

回答by Adam Crume

Anonymous inner classes would generally be the way to go. I find them very readable. However, if the instance of that class ever needs to be serialized (even if only because it's a field of something else), I would strongly recommend using named inner classes. The names of anonymous inner classes in the bytecode can change very easily, and this can break serialization.

匿名内部类通常是要走的路。我发现它们非常具有可读性。但是,如果该类的实例需要序列化(即使只是因为它是其他字段),我强烈建议使用命名的内部类。字节码中匿名内部类的名称很容易改变,这会破坏序列化。

回答by TofuBeer

(Counter point to Daniel Lew)

(反驳丹尼尔·卢)

One disadvantage of anonymous inner classes is that no one can ever use it anywhere else, whereas a named inner class can be used (if only by the class that created it if made private). It's a small distinction, but it does mean that you can help ensure that an inner class is not accidentally recreated elsewhere.

匿名内部类的一个缺点是任何人都不能在其他任何地方使用它,而可以使用命名内部类(如果只被创建它的类设为私有)。这是一个很小的区别,但它确实意味着您可以帮助确保内部类不会在其他地方意外重新创建。

Also, using the anonymous inner class gives anyone reading your code a harder time as they then have to parse this class that came out of nowhere. Using a named inner class you are able to organize the source more.

此外,使用匿名内部类会给任何人阅读您的代码带来困难,因为他们必须解析这个无处不在的类。使用命名的内部类,您可以更多地组织源代码。

I have seen cases where there are two (or more) anonymous inner classes with the exact same code. In GUIs especially (where you may have multiple controls performing the same action) this can crop up (and I am talking production code, not code that my students have written).

我见过两个(或更多)匿名内部类具有完全相同的代码的情况。特别是在 GUI 中(您可能有多个控件执行相同的操作),这可能会突然出现(我说的是生产代码,而不是我的学生编写的代码)。

The readability issue goes both ways, some people find anonymous inner classes better as it lets you see what is going on in once place, others find it a distraction. That part comes down to personal preference.

可读性问题是双向的,有些人发现匿名内部类更好,因为它可以让您一次性看到正在发生的事情,而其他人则认为它会分散注意力。这部分归结为个人喜好。

Also making an class static is more efficient, if you are declaring an anonymous inner class in an instance then there will be more overhead, which, if you don't need access to the instance variables, is wasteful (but probably not worth worrying about until it presents as a problem).

同样使类静态更有效,如果你在一个实例中声明一个匿名内部类,那么将会有更多的开销,如果你不需要访问实例变量,这是浪费的(但可能不值得担心直到出现问题)。

My personal preference is to use non-anonymous classes as they allow for more flexibility when the code is modified later.

我个人的偏好是使用非匿名类,因为它们在以后修改代码时具有更大的灵活性。

回答by user15299

A disadvantage of inner classes is that they can not be static. This means that will hold a reference to the outer class that contains them.

内部类的一个缺点是它们不能是静态的。这意味着将持有对包含它们的外部类的引用。

Non-static inner classes can be an issue. For example we recently had an inner class being serialised, but the outer class was not serializeable. The hidden reference meant that the outer class would also be serialised, which of course failed, but it took a while to find out why.

非静态内部类可能是一个问题。例如,我们最近有一个内部类被序列化,但外部类不可序列化。隐藏引用意味着外部类也将被序列化,这当然失败了,但需要一段时间才能找出原因。

Where I work, static inner classes are encouraged in our coding best practices (where possible) as they carry less hidden baggage and are leaner.

在我工作的地方,我们的编码最佳实践(在可能的情况下)鼓励静态内部类,因为它们携带的隐藏包袱更少,更精简。

回答by Robin

I don't have a problem with simple anonymous classes. But if it consists of more than a few lines of code or a couple of methods, an inner class is more clear. I also think that under certain conditions they should never be used. Such as when they must return data.

我对简单的匿名类没有问题。但是如果它由不止几行代码或几个方法组成,内部类就更清楚了。我还认为在某些情况下永远不应该使用它们。比如什么时候必须返回数据。

I have seen code where a final array of 1 item is used to pass data back from a call to an anonymous inner class. Inside the method of the anon class, the single element is set, then this 'result' extracted once the method is complete. Valid, but ugly code.

我见过这样的代码,其中包含 1 个项目的最终数组用于将数据从对匿名内部类的调用传回。在匿名类的方法中,设置单个元素,然后在方法完成后提取此“结果”。有效但丑陋的代码。

回答by Jeff Grigg

Do the simplest thing that could possibly work: Use the anonymous inner class.

做最简单的事情:使用匿名内部类。

If you later find that you need a broader scope, then refactor the code to support this.

如果您后来发现需要更广泛的范围,请重构代码以支持这一点。

(You would do the same with variables -- putting them in the most specific scope. It makes sense to do the same with other source assets.)

(你可以对变量做同样的事情——把它们放在最具体的范围内。对其他源资产做同样的事情是有意义的。)