В Java вложенные классы могут быть либо, static
либо нет. Если да static
, то они не содержат ссылки на указатель содержащего экземпляра (они также больше не называются внутренними классами, они называются вложенными классами).
Если вы забудете создать вложенный класс, static
когда ему не нужна эта ссылка, это может привести к проблемам со сборкой мусора или анализом выхода.
Можно ли сделать также анонимный внутренний класс static
? Или компилятор вычисляет это автоматически (что могло бы быть, потому что не может быть никаких подклассов)?
Например, если я сделаю анонимный компаратор, мне почти никогда не понадобится ссылка на внешнюю сторону:
Collections.sort(list, new Comparator<String>(){
int compare(String a, String b){
return a.toUpperCase().compareTo(b.toUpperCase());
}
}
java
syntax
inner-classes
Тило
источник
источник
Collections.sort(list, String.CASE_INSENSITIVE_ORDER)
работает с Java 2, читайте, поскольку существует Collection API…Ответы:
Нет, вы не можете, и нет, компилятор не может этого понять. Вот почему FindBugs всегда предлагает заменить анонимные внутренние классы именованными
static
вложенными классами, если они не используют свою неявнуюthis
ссылку.Изменить: Tom Hawtin - tackline говорит, что если анонимный класс создается в статическом контексте (например, в
main
методе), анонимный класс на самом делеstatic
. Но JLS не согласен :В глоссарии Java Roedy Green говорится, что тот факт, что анонимные классы разрешены в статическом контексте, зависит от реализации:
Изменить 2: JLS фактически охватывает статические контексты более явно в §15.9.2 :
Таким образом, анонимный класс в статическом контексте примерно эквивалентен
static
вложенному классу в том смысле, что он не сохраняет ссылку на включающий класс, хотя технически это неstatic
класс.источник
true
с использованием javac (sun-jdk-1.7.0_10) иfalse
компилятора Eclipse.Вид. Анонимный внутренний класс, созданный в статическом методе, очевидно, будет фактически статическим, потому что нет источника для внешнего this.
Между внутренними классами в статических контекстах и статическими вложенными классами есть некоторые технические различия. Если вам интересно, прочтите JLS 3rd Ed.
источник
Я думаю, здесь есть небольшая путаница в номенклатуре, что, по общему признанию, слишком глупо и сбивает с толку.
Как бы вы их ни называли, эти шаблоны (и несколько вариантов с разной видимостью) - все возможные, нормальные, законные Java:
Они учтены в спецификации языка (если вас действительно беспокоит, см. Раздел 15.9.5.1, посвященный статическому методу).
Но эта цитата просто неверна :
Я думаю, что цитируемый автор путает ключевое слово static со статическим контекстом . (Следует признать, что JLS также немного сбивает с толку в этом отношении.)
Честно говоря, все вышеперечисленные шаблоны хороши (как бы вы их ни называли «вложенными», «внутренними», «анонимными» как угодно ...). Действительно, в следующем выпуске Java никто не собирается вдруг убирать эту функциональность. Честно!
источник
new
иJComponent
в третьем примере.Внутренние классы не могут быть статическими - статический вложенный класс не является внутренним классом. Об этом говорится в руководстве по Java .
источник
анонимные внутренние классы никогда не являются статическими (они не могут объявлять статические методы или не финальные статические поля), но если они определены в статическом контексте (статический метод или статическое поле), они ведут себя как статические в том смысле, что они не могут доступ к нестатическим (то есть экземплярам) членам включающего класса (как и ко всему остальному из статического контекста)
источник
Обратите внимание на то, что анонимный внутренний класс становится статическим, вызывая его внутри статического метода.
Это фактически не удаляет ссылку. Вы можете проверить это, попытавшись сериализовать анонимный класс, не делая сериализуемый включающий класс.
источник