在Java中使用匿名类被认为是不好的风格还是好的?

Mne*_*nth 37 java coding-style anonymous-class

我知道在实现Listener和类似的东西时,匿名类可以保存输入.他们试图取代一些封闭用法.

但社区对这种语言特征的价值有何看法?它是否有意义并且您经常使用它吗?它是否使代码更清晰,更易理解,更易于维护?或者匿名类使代码可读性降低?

您对此有什么看法,请举例说明/支持您的意见吗?

coo*_*ird 30

我倾向于使用匿名内部类,在我不需要完成一个完整的类来执行某些任务的情况下.例如,如果我想实现一个ActionListenerRunnable,但我不认为有一个内部类是必要的.例如,对于开始一个简单的Thread,使用匿名内部类可能更具可读性:

public void someMethod()
{
    new Thread(new Runnable() {
        public void run()
        {
            // do stuff
        }
    }).start();
}
Run Code Online (Sandbox Code Playgroud)

在某些情况下,例如上面的例子,它可以提高可读性,特别是对于一次性任务,因为要执行的代码全部写在一个地方.使用内部类会"代理"代码:

public void someMethod()
{
    new Thread(new MyRunnable()).start();
}

// ... several methods down ... //

class MyRunnable implements Runnable
{
    public void run()
    {
        // do stuff
    }
}
Run Code Online (Sandbox Code Playgroud)

也就是说,如果有可能会重复相同事情的情况,它确实应该是一个单独的类,无论是常规类还是内部类.

我倾向于在程序中使用匿名内部类,我只是尝试解决问题而不是将其作为实际应用程序的核心功能.


Pri*_*shi 12

匿名内部类的另一个好用途是当你需要初始化像ArrayList和Set这样的集合时.这种做法也称为双支撑初始化 例如,

private static final Set<String> VALID_CODES = new HashSet<String>() {{
add("XZ13s");
add("AB21/X");
add("YYLEX");
add("AR2D");
}};
Run Code Online (Sandbox Code Playgroud)

显然,这不仅限于收藏品; 它可以用来初始化任何类型的对象 - 例如Gui对象:

 add(new JPanel() {{
setLayout(...);
setBorder(...);
add(new JLabel(...));
add(new JSpinner(...));
}});
Run Code Online (Sandbox Code Playgroud)


Don*_*onX 11

我的观点是匿名类使代码的可读性降低.为了实现监听器,匿名类很有用.对于开发GWT应用程序,匿名类是更好的选择.对于这些情况,如果我们不使用匿名类,则代码行数将增加.


bou*_*tta 6

我们重新使用匿名类.我发现它们很容易用于实现只有一个或两个方法的接口,以及其他地方没有使用的功能.如果你在其他地方再次使用相同的功能,那么应该有一个真正的类可以重用.

  • 或者匿名内部类和它周围的一些代码移动到一个单独的方法中.除此之外,它还会让你的"API"变得更加混乱. (2认同)

小智 6

使用匿名类是提高还是降低易读性是一个品味问题。主要问题肯定不在这里。

匿名类,像内部类一样,携带对封闭类的引用,从而使没有它的东西成为非私有的。简而言之,封闭类的this引用可能会通过内部类逃逸。所以答案是:如果内部类发布自己,那么使用内部类是一种非常糟糕的做法,因为这会自动发布封闭类。例如:

changeManager.register(new ChangeListener() {
    public void onChange(...) {
       ...
    }});
Run Code Online (Sandbox Code Playgroud)

在这里,匿名ChangeLstener被传递给ChangeManagerregister方法。这样做也会自动发布封闭类。

这绝对是一种不好的做法。