Как выводить номер для каждого вызова метода?

206
20 сентября 2017, 10:32

Программа должна выводить несколько void методов. Как сделать так, чтобы при каждом выводе эта строчка получала номер? Я понимаю, что надо использовать цикл, но не пойму как именно его использовать.

Код:

public class Parrot extends Pet {
    private int age;
    public Parrot(int size, String name, int age ) {
        super(size, name);
        this.age = age;
        }
    void eat() {    
    }
    void fly () {
        System.out.println("It can fly very high");
    }
    void getWordsPerDay (int words) {
        System.out.println("It can pronounce " + words + " words per day");
    }
}

Как сделать так, чтобы заданные методы каждый раз при вызове получали порядковый номер?

Например, если вызываются методы eat(), eat(), fly(), eat(), fly(), то выводится 1, 2, 3, 4, 5.

Answer 1

Прямолинейный подход: создать метод, который увеличивает и выводит значение счетчика и вызывать его в каждом из методов:

public class Parrot extends Pet {
     /**
     * Счетчик
     */
     private int callCounter = 0;
     /**
     * Увеличивает и выводит счетчик
     */
     private void countCall() {
         callCounter++;
         System.out.println(callCounter);      
     }
     void eat() {
         countCall();
         ...
     }
     void fly() {
         countCall();
         ... 
     }

Если нужно, чтобы счетчик был общим для разных объектов Parrot, то callCounter и countCall нужно будет объявить как static.

Этот способ требует изменения кода всех методов, по которым нужно считать вызовы. Если по каким-то причинам нужно считать вызовы не изменяя кода, то задача усложняется. Есть следующие варианты:

  • Чтобы считать вызовы для «чужого» класса, можно обернуть его в свой и считать вызовы в обертке.
  • Если нужно автоматизировать процесс, например, отслеживать все вызовы методов по определенным критериям, то можно воспользоваться методами аспектно-ориентированного программирования. Одна из реализаций для Java: AspectJ.
Answer 2

если хочешь поставить счетчик вызова каждого метода, то можно сделать так:

public class Parrot extends Pet {
    private int age;
    private int countFly = 0;
    private int countgetWordsPerDay = 0;
    public Parrot(int size, String name, int age ) {
        super(size, name);
        this.age = age;
        }
    void eat() {    
    }
    void fly () {
        countFly = countFly + 1;
        System.out.println(countFly + ")" + "It can fly very high");        
    }
    void getWordsPerDay (int words) {
        System.out.println(countgetWordsPerDay + ")" + "It can pronounce " + words + " words per day");
    }
}
Answer 3

Чтобы сделать то, что вы хотите достаточно завести статическую переменную и обращаться к ней каждый раз при вызове метода. Но здесь есть один нюанс, если методы вызываются из разных потоков, нужно объявить ее соответствующим потокобезопасным примитивом:

private static final AtomicLong atomicCounter = new AtomicLong(0);

либо обернуть в java.lang.ThreadLocal:

private static final ThreadLocal<Long> threadLocalCounter = new ThreadLocal<>();

Тела методов будут выглядеть соотвественно так:

public void firstMethod() {
    System.out.println(atomicCounter.getAndIncrement());
}

либо:

public void firstMethod() {
    long value = threadLocalCounter.get();
    System.out.println(value);
    threadLocalCounter.set(value + 1);
}
READ ALSO
Что означает эта строчка в логах?

Что означает эта строчка в логах?

Написал программу и собрал её релизную версию, подписал сертификатомПосле установки в логах каждую 1-2 секунды проскакивает эта строчка

170
Android: Как выводить с помощью ORM данные из базы SQLite без интернета?

Android: Как выводить с помощью ORM данные из базы SQLite без интернета?

Я использую: Retrofit 2, Active Android(ORM) и SQLiteСервер написан на Java + Spring

188
Парсинг всего текста из html

Парсинг всего текста из html

Возникла необходимость написать свой краулер on PythonНа данном этапе мне необходимо распарсить весь текст из html и удалить лишнее

161