«__Rvm_do_with_env_before» и «__rvm_after_cd» при выполнении «cd»

Короткий ответ: ментальная модель, которую большинство программистов имеют, как работает область действия, не является моделью, используемой javac. Соответствие более интуитивной модели потребовало бы значительного изменения работы javac.

Основная причина, по которой статические члены во внутренних классах желательны, - это чистота кода - статический член, используемый только внутренним классом, должен жить внутри него, а не быть помещенным во внешний класс. Рассмотрим:

class Outer {
   int outID;

   class Inner {
      static int nextID;
      int id = nextID++;

      String getID() {
         return outID + ":" + id;
      }
   }
}

Рассмотрим, что происходит в getID (), когда я использую неквалифицированный идентификатор «outID». Область видимости этого идентификатора выглядит примерно так:

Outer -> Inner -> getID()

Здесь, опять же, поскольку это как раз то, как работает javac, «внешний» уровень области включает как статические, так и экземпляры Outer. Это запутанно, потому что нам обычно говорят думать о статической части класса как о другом уровне области:

Outer static -> Outer instance -> instanceMethod()
         \----> staticMethod()

В этом способе думать об этом, конечно, staticMethod () может видеть только статические члены Outer. Но если это так, как работает javac, то ссылка на переменную экземпляра в статическом методе приведет к ошибке «имя не может быть разрешено». Что действительно происходит, так это то, что имя найдено в области видимости, но затем добавляется дополнительный уровень проверки и выясняется, что имя было объявлено в контексте экземпляра и ссылается на статический контекст.

OK , как это соотносится с внутренними классами? Наивно мы считаем, что нет внутренних причин, по которым внутренние классы не могут иметь статическую область видимости, потому что мы представляем область, которая работает следующим образом:

Outer static -> Outer instance -> Inner instance -> getID()
         \------ Inner static ------^

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

Это не так, как работает javac - существует один уровень видимости как для статических, так и для экземпляров, а область всегда строго гнездится. Даже наследование реализуется путем копирования объявлений в подкласс, а не разветвления и поиска в области суперкласса.

Чтобы поддерживать статические члены внутренних классов, javac должен был либо разделить статические и экземплярные области и поддерживают ветвление и воссоединяют иерархии областей, или ему придется расширить свою простую логическую идею «статического контекста», чтобы изменить отслеживание типа контекста на всех уровнях вложенного класса в текущей области.

13
задан AdamT 5 July 2012 в 04:20
поделиться