是否可以在Java静态中创建匿名内部类? [英] Is it possible to make anonymous inner classes in Java static?

查看:98
本文介绍了是否可以在Java静态中创建匿名内部类?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Java中,嵌套类可以是 static 。如果它们是 static ,它们不包含对包含实例的指针的引用(它们也不再被称为内部类,它们被称为嵌套类)。



如果不需要该引用,忘记创建嵌套类 static 会导致垃圾收集或转义分析出现问题。



是否可以制作匿名内部类 static ?或者编译器会自动解决这个问题(可能会出现这种情况,因为不能有任何子类)?



例如,如果我创建一个匿名比较器,我几乎不需要对外部的引用:

  Collections.sort(list,new Comparator< String>(){
int compare (String a,String b){
return a.toUpperCase()。compareTo(b.toUpperCase());
}
}


解决方案

不,你不能,也不,编译器无法弄明白。这就是为什么FindBugs总是建议将匿名内部类更改为命名为 static 的嵌套类,如果它们不使用它们的隐式这个引用。



编辑: Tom Hawtin - 标语说如果匿名类是在静态上下文中创建的(例如在 main 方法),匿名类实际上是 static 。但是JLS 不同意


匿名类永远不会是 abstract (§8.1.1.1)。匿名类始终是内部类(第8.1.3节);它永远不会是 static (§8.1.1,§8.5.1)。匿名类总是隐式 final (§8.1.1.2)。


Roedy Green的Java词汇表表示在静态上下文中允许匿名类的事实取决于实现:


如果你想阻止那些维护你的代码,wags发现了 javac.exe 将允许 static init代码和 static 方法中的匿名类,即使语言规范说的是匿名类,从不静态。当然,这些匿名类无法访问该对象的实例字段。我不建议这样做。 功能可以随时提取。


编辑2: JLS实际上在§15.9.2


C 成为实例化的类,让 i 成为正在创建的实例。如果 C 是内部类,那么 i 可能有一个立即封闭的实例。立即封闭的 i (§8.1.3)实例确定如下。




  • 如果 C 是一个匿名类,然后:


    • 如果类实例创建表达式出现在静态上下文中(第8.1.3节),那么 i 没有立即封闭的实例。

    • 否则, i 的直接封闭实例是



因此,静态上下文中的匿名类大致相当于 static 嵌套类,因为它不保留对封闭类的引用,即使它在技术上不是 static 类。 / p>

In Java, nested classes can be either static or not. If they are static, they do not contain a reference to the pointer of the containing instance (they are also not called inner classes anymore, they are called nested classes).

Forgetting to make an nested class static when it does not need that reference can lead to problems with garbage collection or escape analysis.

Is is possible to make an anonymous inner class static as well? Or does the compiler figure this out automatically (which it could, because there cannot be any subclasses)?

For example, if I make an anonymous comparator, I almost never need the reference to the outside:

  Collections.sort(list, new Comparator<String>(){
       int compare(String a, String b){
          return a.toUpperCase().compareTo(b.toUpperCase());
       }
  }

解决方案

No, you can't, and no, the compiler can't figure it out. This is why FindBugs always suggests changing anonymous inner classes to named static nested classes if they don't use their implicit this reference.

Edit: Tom Hawtin - tackline says that if the anonymous class is created in a static context (e.g. in the main method), the anonymous class is in fact static. But the JLS disagrees:

An anonymous class is never abstract (§8.1.1.1). An anonymous class is always an inner class (§8.1.3); it is never static (§8.1.1, §8.5.1). An anonymous class is always implicitly final (§8.1.1.2).

Roedy Green's Java Glossary says that the fact that anonymous classes are allowed in a static context is implementation-dependent:

If you want to baffle those maintaining your code, wags have discovered javac.exe will permit anonymous classes inside static init code and static methods, even though the language spec says than anonymous classes are never static. These anonymous classes, of course, have no access to the instance fields of the object. I don’t recommend doing this. The feature could be pulled at any time.

Edit 2: The JLS actually covers static contexts more explicitly in §15.9.2:

Let C be the class being instantiated, and let i be the instance being created. If C is an inner class then i may have an immediately enclosing instance. The immediately enclosing instance of i (§8.1.3) is determined as follows.

  • If C is an anonymous class, then:
    • If the class instance creation expression occurs in a static context (§8.1.3), then i has no immediately enclosing instance.
    • Otherwise, the immediately enclosing instance of i is this.

So an anonymous class in a static context is roughly equivalent to a static nested class in that it does not keep a reference to the enclosing class, even though it's technically not a static class.

这篇关于是否可以在Java静态中创建匿名内部类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆