2011-01-11 2 views
9

Недавно я наткнулся на следующий фрагмент в существующей кодовой базе, над которой я работаю, и добавил комментарий, который вы видите там. Я знаю, что этот конкретный фрагмент кода можно переписать, чтобы быть более чистым, но мне просто интересно, правильный ли мой анализ.Является ли объявление многих идентичных классов анонимных классов в java?

Будет ли java создавать новое объявление класса и хранить его в пространстве perm gen для каждого вызова этого метода, или он будет знать, чтобы повторно использовать существующее объявление?

protected List<Object> extractParams(HibernateObjectColumn column, String stringVal) { 
    // FIXME: could be creating a *lot* of anonymous classes which wastes perm-gen space right? 
    return new ArrayList<Object>() { 
     { 
      add(""); 
     } 
    }; 
} 
+0

Но, возможно, использование внутреннего класса, а не статического вложенного класса, отнимает немного памяти для внешнего $ this указателя (в случае, если это не требуется). Это была бы куча памяти. – Thilo

+0

Дублирующий код загромождает ваш код и затрудняет его поддержание, это должно быть больше беспокоиться. –

ответ

15

Класс будет компилироваться только один раз (во время компиляции). Компилятор извлекает класс (названный как-то вроде MyOuterClass$1) и использует его. Конечно, это создаст несколько экземпляров, но все они будут одного класса. Вы можете видеть, что когда вы скомпилируете файл .java и посмотрите на созданные файлы .class - для внутреннего анонимного класса будет один.

5

Нет, что создает много экземпляров один одного класса. Для того, чтобы проверить, поставить это в пределах вашего анонимного класса:

@Override 
public String toString() { 
    return getClass().getName(); 
} 

Затем вызовите toString() на различных экземпляров анонимного класса. Вы увидите, что все они возвращают одно и то же имя класса.

3

Другие ответы верны.

Однако:

  • Если эта схема повторяется несколько раз в вашем коде, то вы будет в конечном итоге с равным количеством внутренних классов. Если вы используете шаблон сотни/тысячи раз, увеличенное использование кода/подменного кода может быть значительным.

  • Что вы делаете в этом конкретном примере, может быть выражено более просто как

    protected List<Object> extractParams(HibernateObjectColumn column, 
                String stringVal) { 
        return Collections.singletonList(""); 
    } 
    
  • В тех случаях, когда вы должны заполнить список с несколькими значениями, решение с участием статический вспомогательный метод, вероятно, проще ,

+0

ах, имеет смысл, спасибо. в этом конкретном случае я, вероятно, заменим его на Arrays.asList (""), поскольку Collections.singletonList ("") предоставит неизменный список, и, возможно, код клиента изменяет результат. – depsypher

+0

Да - 'Arrays.asList (...)' - лучшее решение. –

+0

@depsypher Однако помните, что результат 'Arrays.asList' по-прежнему не может быть изменен. Единственное, что вы можете сделать (в этом случае), что 'Collections.singletonList' не может использовать' list.set (0, ...) '. Кроме того, API-интерфейсы становятся чище при возврате неизменяемых списков.Callers действительно должны клонировать список, когда они хотят его изменить; копии неполного списка не дорогие. –

0

ли декларирование много идентичных анонимной памяти классов отходов в Java?

Конечно, это так, но вы не делаете этого в коде, который вы опубликовали.

+0

Он определенно объявляет один анонимный класс. Я думаю, что коннотация состоит в том, что он будет иметь этот код во многих местах. – tster

+0

@tster Точно. Он объявляет один анонимный класс. Не много'. Никакой коннотации не требуется. Он явно спрашивает: «Будет ли Java создавать новое объявление класса и хранить его в пространстве perm gen для каждого вызова этого метода?». Это не так. – EJP

Смежные вопросы