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

发布于 2024-07-13 06:32:52 字数 1431 浏览 7 评论 0原文

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(15

柠檬心 2024-07-20 06:32:52

当我不需要一个完整的类来执行某些任务时,我倾向于使用匿名内部类。 例如,如果我想实现 ActionListenerRunnable,但我认为没有必要使用内部类。 例如,对于启动一个简单的线程,使用匿名内部类可能更具可读性:

public void someMethod()
{
    new Thread(new Runnable() {
        public void run()
        {
            // do stuff
        }
    }).start();
}

在某些情况下,例如上面的示例,它可以提高可读性,特别是对于一次性任务,因为要执行的代码全部写在一处。 使用内部类会使代码“非本地化”:

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

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

class MyRunnable implements Runnable
{
    public void run()
    {
        // do stuff
    }
}

但是,也就是说,如果在某些情况下会重复相同的事情,那么它确实应该是一个单独的类,无论是常规类还是内部类。

我倾向于在程序中使用匿名内部类,我只是在尝试一些事情,而不是将其作为实际应用程序的核心功能。

I tend to use anonymous inner classes in situations where I don't need to have a full-blown class just to perform some task. For example, if I want to implement an ActionListener or Runnable, but I don't think having an inner class would be necessary. For example, for starting a simple Thread, using an anonymous inner class might be more readable:

public void someMethod()
{
    new Thread(new Runnable() {
        public void run()
        {
            // do stuff
        }
    }).start();
}

In certain cases, such as the example above, it can increase readability, especially for one-time tasks, as the code that is to be executed is all written in one spot. Using an inner class would "delocalize" the code:

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

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

class MyRunnable implements Runnable
{
    public void run()
    {
        // do stuff
    }
}

That said, however, if there is going to be cases where the same thing is going to be repeated, it should indeed be a separate class, be it a regular class or an inner class.

I tend to use anonymous inner classes in programs where I am just trying things out rather than have it as a central feature of an actual application.

烟沫凡尘 2024-07-20 06:32:52

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

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

显然这不仅限于集合; 它可以用来初始化任何类型的对象——例如 Gui 对象:

 add(new JPanel() {{
setLayout(...);
setBorder(...);
add(new JLabel(...));
add(new JSpinner(...));
}});

One more good use of anonymous inner class is when you need to initialize collections like ArrayList and Set. This practice is also known as double brace initialization
For example ,

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

Obviously, this is not limited to collections; it can be used to initialize any kind of object -- for example Gui objects:

 add(new JPanel() {{
setLayout(...);
setBorder(...);
add(new JLabel(...));
add(new JSpinner(...));
}});
何以心动 2024-07-20 06:32:52

我的观点是匿名类使代码的可读性较差。 对于实现侦听器,匿名类很有用。 对于开发 GWT 应用程序,匿名类是更好的选择。
对于这些情况,如果我们不使用匿名类,那么代码行数将会增加。

My opinion is anonymous classes makes the code less readable. For implementing listeners anonymous classes are useful. For developing a GWT application anonymous classes are the better choice.
For these cases, if we are not using anonymous classes then the number of lines of code will increase.

再可℃爱ぅ一点好了 2024-07-20 06:32:52

我们经常使用匿名类。 我发现它们很容易用于实现只有一两个方法的接口,并且该功能在其他任何地方使用。 如果您在其他地方再次使用相同的功能,则应该有一个真正的类可以重用。

We use anonymous classes regurlarly. I find them easy to use for implementing interfaces that have only one or two methods and that where the functionality isn't used anywhere else. If you use the same functionality again somewhere else there should be a real class to be reused.

预谋 2024-07-20 06:32:52

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

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

changeManager.register(new ChangeListener() {
    public void onChange(...) {
       ...
    }});

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

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

Whether using anonymous class improves or degrades legibility is a matter of taste. The main issue is definitely not here.

Anonymous classes, like inner classes, carries a reference to the enclosing class, thus making non private things that without it would be. To be short, the this reference of the enclosing class may escape through the inner class. So the answer is: it is a very bad practice to use an inner class if it published itself, since that would automatically publish the enclosing class. for example:

changeManager.register(new ChangeListener() {
    public void onChange(...) {
       ...
    }});

Here, the anonymous ChangeLstener is passed to the register method of a ChangeManager. Doing so will automatically publish the enclosing class as well.

This is definitely a bad practice.

早茶月光 2024-07-20 06:32:52

我主要将匿名类用于只有一个方法的接口,即 可运行动作监听器。 大多数较大的接口都在现有的类中保证它们自己的类或实现。 因为这是我的观点,所以我不需要论证来支持它。

I use anonymous classes mostly for interfaces that have only a single method, i.e. Runnable or ActionListener. Most larger interfaces warrent their own classes or implementation in an already existing class. And as it is my opinion I don’t need arguments to support it.

他夏了夏天 2024-07-20 06:32:52

如果尽可能限制范围和访问是一件好事,那么匿名类就非常好。 它们的范围仅限于需要它们的一类。 如果合适的话,我会说匿名类很好。

一旦你复制相同的功能,它就变成了一个坏主意。 将其重构为独立的公共类。 具有重构功能的 IDE 让这一切变得简单。

If limiting scope and access as much as possible is a good thing, then anonymous classes are very good. They are limited in scope to the one class that needs them. When that's appropriate, I'd say anonymous classes are good.

The instant you duplicate the same function, it becomes a bad idea. Refactor it into a public class that stands on its own. IDEs with refactoring features make that easy.

ゝ偶尔ゞ 2024-07-20 06:32:52

匿名类主要出现在 GUI 应用程序中,专门用于事件处理。匿名类在实现包含一两个方法的小型接口的情况下非常有用。例如,您有一个类,其中有两个或三个线程,并且您想要使用这些线程执行两个或三个不同的任务。在这种情况下,您可以借助匿名类来执行您想要的任务。 查看以下示例

class AnonymousClass{

public static void main(String args[]){


    Runnable run1=new Runnable(){

        public void run(){

            System.out.println("from run1");
        }

    };
    Runnable run2=new Runnable(){

        public void run(){

            System.out.println("from run2");
        }

    };
    Runnable run3=new Runnable(){

        public void run(){

            System.out.println("from run3");
        }

    };



    Thread t1=new Thread(run1);
    Thread t2=new Thread(run2);
    Thread t3=new Thread(run3);


    t1.run();t2.run();t3.run();

}
}

输出:

来自运行1

来自运行2

来自运行3

在上面的代码片段中,我使用了三个线程来执行三个不同的任务。 看,我创建了三个匿名类,其中包含 run 方法的实现来执行三个不同的小任务。

Anonymous class is mostly seen in GUI application specially for events handling.Anonymous class is useful in cases of implementing small interfaces that contains one or two methods..For example.. you have a class where you have two or three threads and you want to perform two or three different tasks using those threads.In this situation you can take the help of anonymous class to perform your desired tasks. look at the follow example

class AnonymousClass{

public static void main(String args[]){


    Runnable run1=new Runnable(){

        public void run(){

            System.out.println("from run1");
        }

    };
    Runnable run2=new Runnable(){

        public void run(){

            System.out.println("from run2");
        }

    };
    Runnable run3=new Runnable(){

        public void run(){

            System.out.println("from run3");
        }

    };



    Thread t1=new Thread(run1);
    Thread t2=new Thread(run2);
    Thread t3=new Thread(run3);


    t1.run();t2.run();t3.run();

}
}

output:

from run1

from run2

from run3

In the above snap of code i have used three threads to perform three different tasks. Look i have created three anonymous classes that contains the implementation of the run method to perform three different small tasks.

半世蒼涼 2024-07-20 06:32:52

使用它们是有意义的,但您必须了解它们下面正在做什么。 只有当我需要一个类来完成一些我在其他地方不需要的非常具体的事情时,我才使用它们。

It makes sense to use them, but you must be aware of whats being done underneath. I only use them if I need a class to do something very specific that I don't need anywhere else.

有木有妳兜一样 2024-07-20 06:32:52

这取决于你将它们与什么进行比较。 我宁愿拥有它们也不愿没有它们,但我宁愿能够为 Arrays.sort() 等方法提供纯代码块,而不是必须显式创建一个包含我的compare() 实现的类。

It depends what you compare them to. I'd rather have them than not have them, but then I'd rather be able to supply plain code blocks to methods like Arrays.sort() than having to explicitly create a class containing my implementation of compare().

你的心境我的脸 2024-07-20 06:32:52

我主要使用匿名类
a) 简写符号,如果接口有一个或两个方法,并且不会影响可读性

b) 我无法证明创建新类的合理性的情况,例如在 swing 中,当您必须附加一个动作监听器来让 JButton一些琐碎的操作。

I use Anonymous classes mostly
a) shorthand notation if the interface has one or two methods and it wont affect the readability

b) situation where I wont be able to justify creation of a new class, for example In swing when you have to attach an actionlistner to lets a JButton for some trivial operation.

弃爱 2024-07-20 06:32:52

我同意许多其他人所说的,因为它们对于仅使用一次的小型接口很有用。 但我还要添加一个限制,即如果必须更改匿名类外部的代码才能使其正常工作,则不要使用匿名类。

如果您必须开始将变量声明为 Final 来容纳匿名类,因为它引用了它们,那么请改用内部类。 我还看到了一些不好的代码味道,其中使用最终数组(大小为 1)从匿名类返回结果。

I agree with what many others have said in that they are useful for small interfaces when only used once. But I would also add the restriction that if code external to the anonymous class has to be altered for it to work, then don't use an anonymous class.

If you have to start declaring variables as final to accommodate the anon class since it references them, then use an inner class instead. I have also seen some bad code smells where final arrays (of size 1) are used to return results from anon classes.

魄砕の薆 2024-07-20 06:32:52

匿名类没有本质上的不同或特殊之处。 它们最终只是语法糖,支持引用外部类。 这使得编写适配器变得更容易 - 就像集合框架返回的大多数迭代器实现一样。

There is nothing inherently different or special about anonymous classes. They are ultimately just syntactical sugar with support for referencing the outer class. This makes it easier to author adapters - just like most of the Iterator implementations returned by the Collections framework.

忆伤 2024-07-20 06:32:52

匿名类不会“隐藏”代码,但它们确实会降低其可重用性。 请注意,这也适用于闭包。

在某些方面,它们允许一些很好的重构,因为您可以将代码传递到方法中。 这可以非常有效地用来减少重复,我当然不反对匿名类/闭包,但是在某些情况下它们可能是一个缺点。

首先考虑您传入的匿名内部类代码不适合在您的代码中重用。 如果您在其他代码中执行相同的操作,则必须将其重写为匿名内部类以外的其他内容才能重用它,此时甚至可能很难知道其他地方有代码可以使用重复使用。

除了缺乏重用之外,参数化也很困难,这导致了我最大的抱怨……它们往往会导致复制和粘贴代码。

我见过很多 GUI,其中有人从匿名内部类作为事件响应者开始。 许多人必须做一些稍微不同的事情,例如,5 行代码,唯一的区别是中间的字符串。 一旦您习惯了使用内部类,简单的解决方案就是复制并粘贴该块并替换该字符串。

此时很少有人会想到创建一个具有字符串参数的新“命名”类并将该类传递给所有方法的解决方案。 这个命名类可以使用参数或继承来定义不同的行为和代码。

我是闭包的粉丝,并且不讨厌匿名类——只是指出我看到的一些陷阱。

Anonymous classes don't "Hide" code but they do TEND to make it slightly less reusable. Note that this applies to closures as well.

In some ways they allow some nice refactors because you are allowed to pass code into a method. This can be used very effectively to reduce duplication and I'm certainly not against Anonymous classes/closures, however there are a few cases where they can be a drawback.

First consider that the anonymous inner class code you are passing in does not lend itself to reuse in your code. If you are doing the same thing in some other code you'd have to re-write it as something other than an anonymous inner class in order to reuse it and at that point it could be difficult to even know that there is code elsewhere to reuse.

Along with the lack of reuse is it's difficulty to parameterize, which leads to my biggest complaint... they tend to lead to copy and paste code.

I've seen quite a few GUIs where someone started with anonymous inner classes as event responders. Many had to do something slightly different, For instance, 5 lines of code where the only difference is a string in the middle. Once you are in the habit of using inner classes the easy solution is to copy and paste the block and replace that string.

The solution of creating a new "Named" class that has a string parameter and passing that class to all the methods rarely occurs to someone at that point. This named class can use parameters or inheritance to define different behaviors as well as code.

I'm a fan of closures and don't hate anonymous classes--just pointing out some pitfalls I've seen.

新人笑 2024-07-20 06:32:52

因此,借助 java 8 接口中静态方法的新功能,您可以使用匿名内部类来返回接口的实例。 例如:

interface Person {
 String getName();
 int getAge();

 static Person newInstance() {
   return new Person() {
     public String getName() {
        return "Bob";
     }

     public int getAge() {
        return 99;
     }
   } 
 }
}

您可以像这样获得一个实例:

Person person = Person.newInstance();

基本上,这允许您的接口有一个默认实现。

So with java 8 new feature of static methods in interfaces, you can use an anonymous inner class to return an instance of your interface. For example:

interface Person {
 String getName();
 int getAge();

 static Person newInstance() {
   return new Person() {
     public String getName() {
        return "Bob";
     }

     public int getAge() {
        return 99;
     }
   } 
 }
}

And you can get an instance like so:

Person person = Person.newInstance();

Basically this allows for a single default implementation of your interface.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文