2015-11-30 50 views
4

我遇到了一些包含匿名类的代码。我以前没有见过匿名课,所以我对他们做了一些研究。何时使用匿名类?

我感兴趣的主要领域是java,所以我查了Oracle's tutorial of anonymous classes.我理解机制,我看到了示例的要点,但在我看来,使用匿名类会使代码难以阅读,并且会导致很多头痛。

有没有任何情况下,它是不可避免的使用匿名类或建议使用它们而不是命名类?

+2

该文档说:匿名类使您可以使您的代码更加简洁。它们使您能够同时声明和实例化一个类。除了没有名字之外,它们就像本地的课程。如果您只需要使用一次本地课程,请使用它们。 –

+2

我完全同意'匿名'和'内部'类可以使代码难以阅读和开玩笑,但他们也可以澄清很多很少的需要。它们是你手中的工具,只是在你的选择中是明智的。 –

+1

匿名内在类是那些谚语的双刃剑之一。 – biziclop

回答

4

是否有任何情况下,当不可避免地要使用匿名类

没有,你总是可以使用一个私有的内部类而不是一个匿名类。


使用匿名类使得代码难以阅读和可能会导致很多头痛

的这很大程度上取决于你如何使用匿名类。请看下面的例子:

new Thread(new Runnable() { 
    @Override 
    public void run() { 
     // do something 
    } 
}).start(); 

在这个例子中,你创建一个由一个线程上运行一个Runnable。如果你不会使用匿名类,你不得不把它写成如下:

private class SomeClass implements Runnable { 
    @Override 
    public void run() { 
     // TODO Auto-generated method stub 

    } 
} 

,并用它作为:

new Thread(new SomeClass()).start(); 

随着第一种可能性,你可以直接看到线程是什么在第二种可能性中,你首先必须找到这里使用的类。


匿名类的另一个优点。您可以做到以下几点:

// define some constant which can be used in the anonymous class: 
final String someStr = "whatever"; 

new Thread(new Runnable() { 
    @Override 
    public void run() { 
     // use the String someStr directly 
     System.out.println(someStr); 
    } 
}).start(); 

您可以使用它在匿名类中定义的代码中声明常量。如果你使用私有的内部类,你必须将这些常量赋予类的构造函数才能使用它们!

4

通过隐式定义新类,您总是可以避免使用匿名类。但是在某些情况下,最好使用匿名类。考虑下面的例子:

void main() { 
    new Thread(new Runnable(){ 
     public void run() { 
     System.out.println("Hello world"); 
     } 
    }).start(); 
} 

上面的代码片段更易读,更短,然后定义新的类。

public class MyRunnable implements Runnable { 
    public void run() { 
    System.out.println("Hello world"); 
    } 
} 


void main() { 
    new Thread(new MyRunnable()).start(); 
} 

在Java 8 labmda可以用来代替匿名类在某些情况下

Runnable task =() -> { System.out.println("hello world"); }; 
new Thread(task).start(); 
+0

Lambdas与匿名类概念无关,但与Functional接口(仅有一个方法的接口)有关。 – Prim

+2

@Prim他们非常相关,但并不总是可以互换的。 – biziclop

+2

@biziclop是的,但回答说''在Java 8 labmda可以用来代替匿名类“'这是不正确的。只有当它是一个实现了功能接口的不同类别时才是如此 – Prim

2

有没有任何情况下,它是不可避免的使用匿名类...

不,您可以随时为其定义一个命名类。匿名类的要点是在只需要一次类的情况下使代码更加简洁和紧凑。

建议使用它们而不是命名类?

它取决于正在创建的类的上下文。

如果您正在实现只有一个函数(即Runnable)的接口,那么使用lambda表达式而不是匿名类不是一个不错的选择。 lamba expression