Как for loop работает с экземпляром?

#java #log4j

#java #log4j

Вопрос:

При поиске метода, который на самом деле записывает журнал в файл в библиотеке log4j, нашел приведенный ниже метод

   public void callAppenders(LoggingEvent event) {
    int writes = 0;
    for (Category c = this; c != null; c = c.parent) {
      synchronized (c) {
        if (c.aai != null) {
          writes  = c.aai.appendLoopOnAppenders(event);
        }
        if (!c.additive) {
          break;
        }
      }
    }
    if (writes == 0) {
      this.repository.emitNoAppenderWarning(this);
    }
  }
  

Но я не могу понять, что происходит в цикле for. Кто-нибудь может помочь мне понять, что здесь повторяется? Никогда не сталкивался с таким фрагментом кода ..!

Обновить:

У меня есть код, в котором он использует один метод для входа в файлы журналов. И в рамках этого метода он вызывает приведенный ниже метод, который поступает из библиотеки log4j

   public void log(String callerFQCN, Priority level, Object message, Throwable t) {
    if (this.repository.isDisabled(level.level)) {
      return;
    }
    if (level.isGreaterOrEqual(getEffectiveLevel())) {
      forcedLog(callerFQCN, level, message, t);
    }
  }
  

И отсюда метод forcedLog

   protected void forcedLog(String fqcn, Priority level, Object message, Throwable t) {
    callAppenders(new LoggingEvent(fqcn, this, level, message, t));
  }
  

это вызывает, наконец, callAppenders метод, упомянутый сверху. И protected volatile Category parent; присутствует в категории class, где все вышеперечисленные методы также являются частью этого класса.

Спасибо

Комментарии:

1. Без представления о вашем опыте работы с Java, как кто-нибудь узнает, с чего начать — или остановиться? Пожалуйста, отредактируйте в своем вопросе, какова ваша идея о том, что такое экземпляр class Category и какой цели parent служит элемент данных экземпляра.

2. @greybeard, вопрос обновлен ..! Пожалуйста, проверьте сейчас ..!

Ответ №1:

Вероятно, вы привыкли видеть циклы, подобные

 for (int i=0; i<10; i  ) { ... }
  

и поймите, что это повторяется i от 0 ниже 10 , т. е. 9 .

Возможно, синтаксис этого цикла показался вам немного странным, но у вас никогда не возникало более глубоких мыслей по этому поводу. Итак, давайте сделаем это сейчас.

  • Первая часть int i=0 — это оператор, который создает начальное состояние итерации. Здесь он определяет новую целочисленную переменную с именем i и инициализирует ее как become 0 . Вот почему этот цикл начинается с 0.
  • Вторая часть i<10 представляет собой логическое выражение, которое решает, следует ли (далее) выполнять тело цикла. Этот определяет, что цикл должен повторяться до тех пор, пока i значение меньше 10 .
  • Третья часть i определяет, что изменять от итерации к итерации. Здесь он увеличивается i на 1 .

Теперь давайте взглянем на фрагмент

 for (Category c = this; c != null; c = c.parent) { ... }
  
  • Первая часть Category c = this создает новую переменную типа Category и инициализирует ее как become this . Итак, для первой итерации c будет this .
  • Вторая часть c != null определяет, что цикл повторяется до тех пор, пока категория c не null станет.
  • Третья часть c = c.parent определяет, что каждая следующая итерация цикла использует родительский элемент текущей категории.

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

Итак, итерации являются:

  • c = this;
  • c = this.parent;
  • c = this.parent.родительский;
  • c = this.parent.parent.родительский;

до тех пор, пока c не станет null (потому что у самого некоторого конечного родителя есть нулевой родитель). Тело цикла не создает и не изменяет никаких экземпляров категорий, что означает, что цикл просто следует родительской иерархии категорий, которая была установлена перед запуском цикла.

Итак, если до сих пор вы использовали только for (int i=0; i<10; i ) { ... } шаблон, вы упустили большую часть мощности и гибкости for цикла.

Комментарии:

1. спасибо, теперь я могу работать с базовым циклом for .. но parent — это переменная экземпляра самого типа класса (Category ). Тогда кто управляет этим для нового значения после запуска цикла …?

2. @Lenny: Базовый оператор for в Java состоит из трех частей, разделенных ; , последняя из которых является ForUpdate частью . Он выполняется непосредственно перед повторной оценкой 2-й части: управляющего выражения . В рассматриваемом коде эта 3-я часть содержит только одно выражение: c = c.parent , которое «заставляет c подниматься по дереву категорий». (Для навязчиво односвязного списка node = node.next может перемещаться по списку.) Члены данных (» instance variable s») control управляются методами своих экземпляров, если это возможно.