Я не думаю, что здесь есть что добавить, большинство ответов прекрасно объясняют различия между статическим вложенным классом и внутренними классами. Однако рассмотрите следующую проблему при использовании вложенных классов и внутренних классов. Как упоминание в нескольких ответах, внутренние классы не могут быть созданы без экземпляра и их вмещающего класса, что означает, что они удерживают указатель на экземпляр их вмещающего класса, что может привести к переполнению памяти или исключению переполнения стека из-за того, что GC не смогут мусор собирать окружающие классы, даже если они больше не используются. Чтобы сделать это, проверьте следующий код:
public class Outer {
public class Inner {
}
public Inner inner(){
return new Inner();
}
@Override
protected void finalize() throws Throwable {
// as you know finalize is called by the garbage collector due to destroying an object instance
System.out.println("I am destroyed !");
}
}
public static void main(String arg[]) {
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
// out instance is no more used and should be garbage collected !!!
// However this will not happen as inner instance is still alive i.e used, not null !
// and outer will be kept in memory until inner is destroyed
outer = null;
//
// inner = null;
//kick out garbage collector
System.gc();
}
Если вы удалите комментарий на // inner = null;
, программа выйдет «Я уничтожен!», Но если оставить комментарий, это не будет. Причина в том, что белый внутренний экземпляр по-прежнему ссылается, GC не может его собрать и потому что он ссылается (имеет указатель на) внешний экземпляр, который он также не собирает. Наличие достаточного количества этих объектов в вашем проекте и может закончиться нехваткой памяти. По сравнению со статическими внутренними классами, которые не содержат точку для внутреннего экземпляра класса, поскольку он не связан с экземпляром, а связан с классом. Вышеупомянутая программа может печатать «Я уничтожен!» если вы станете классом Inner static и инстанцируются с помощью Outer.Inner i = new Outer.Inner();
SnippetsEmu является полезным плагином отрывков.
Если SnippetsEmu слишком тяжел или амбициозен к тому, в чем Вы нуждаетесь (это было для меня), я записал плагин, который управляет отрывками на основе типа файла. Это даже имеет заполнение клавишей Tab при выборе отрывка!:)
Получают его здесь: snippets.vim
Как отмечено MDCore, SnippetsEmu является популярным сценарием Vim, который делает просто это и т.д. При необходимости только в расширении (не пятясь каре), можно использовать стандарт :ab[breviate]
команда.
:ab[breviate] [<expr>] {lhs} {rhs}
add abbreviation for {lhs} to {rhs}. If {lhs} already
existed it is replaced with the new {rhs}. {rhs} may
contain spaces.
See |:map-<expr>| for the optional <expr> argument.
Snipmate - как texmate :) http://www.vim.org/scripts/script.php?script_id=2540
видео: http://vimeo.com/3535418
snippet def
""" ${1:docstring} """
def ${2:name}:
return ${3:value}