Как избавиться от кучи If (swich-case - тоже не подойдет) П.С. Аннотации написаны по аналогии с аннотациями JUnit4, просто с припиской "Сat"

Методы сортируются в ArrayList-ы, в зависимости от аннотации над методом.

public class CatTestMainClass {
    public Class inputTestClass;

    ArrayList<Method> methodsWithCatBeforeClassAnnotation = new ArrayList<>();
    ArrayList<Method> methodsWithCatBeforeAnnotation = new ArrayList<>();
    ArrayList<Method> methodsWithTheOnlyCatTestAnnotation = new ArrayList<>();
    ArrayList<Method> methodsWithCatAfterAnnotation = new ArrayList<>();
    ArrayList<Method> methodsWithCatAfterClassAnnotation = new ArrayList<>();
    ArrayList<Method> methodsWithCatIgnoreAnnotation = new ArrayList<>();
    ArrayList<Method> methodsWithCatTimeAnnotation = new ArrayList<>();

    public CatTestMainClass(Class catTestClass) {
        inputTestClass = catTestClass;
    }

    public void methodSortingByAnnotations() {
        Method[] declaredMethods = inputTestClass.getDeclaredMethods();
        for (Method method : declaredMethods) {
            if (!method.isAnnotationPresent(CatIgnore.class)) {
                if (method.isAnnotationPresent(CatBeforeClass.class))
                    methodsWithCatBeforeClassAnnotation.add(method);
                if (method.isAnnotationPresent(CatBefore.class))
                    methodsWithCatBeforeAnnotation.add(method);
                if (method.isAnnotationPresent(CatTest.class)
                        && !method.isAnnotationPresent(CatBeforeClass.class)
                        && !method.isAnnotationPresent(CatBefore.class)
                        && !method.isAnnotationPresent(CatAfter.class)
                        && !method.isAnnotationPresent(CatAfterClass.class))
                    methodsWithTheOnlyCatTestAnnotation.add(method);
                if (method.isAnnotationPresent(CatAfter.class))
                    methodsWithCatAfterAnnotation.add(method);
                if (method.isAnnotationPresent(CatAfterClass.class))
                    methodsWithCatAfterClassAnnotation.add(method);
                if (method.isAnnotationPresent(CatTime.class)) {
                    methodsWithCatTimeAnnotation.add(method);
                }
            } else {
                methodsWithCatIgnoreAnnotation.add(method);
            }
        }
    }
}

Ответы (2 шт):

Автор решения: Alexey R.

Можно так: создаем мапу где ключ - это аннотация, а значение - обработчик метода. Каждый обработчик записывает метод в определенный список. Далее бежим по мапе и проверяем аннотирован ли какой-либо метод аннотацией. Если да, вызываем соответствующий обработчик для этого метода.

package click.webelement.sandbox;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

interface MySorter{
    void doSort(Method method);
}

public class MethodSorting {

    List<Method> list1 = new ArrayList<>();
    List<Method> list2 = new ArrayList<>();

    public static void main(String[] args) {
        new MethodSorting().sorting(MethodSorting.class);
    }

    private void sorting(Class testClass){
        Map<Class, MySorter> classSorterMap = new HashMap<>();
        classSorterMap.put(Annotation1.class, method -> {list1.add(method);});
        classSorterMap.put(Annotation2.class, method -> {list2.add(method);});
        classSorterMap.forEach((aClass, mySorter) -> {
            for(Method method: testClass.getDeclaredMethods()){
                if(method.isAnnotationPresent(aClass)){
                    mySorter.doSort(method);
                }
            }
        });
        System.out.println("Stop here to debug");
    }

    @Annotation1
    void test1(){}

    @Annotation2
    void test2(){}

}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@interface Annotation1 {}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@interface Annotation2 {}

Это в целом прототип подхода, но не полное решение, т.к. в Вашем случае есть корнер-кейс с несколькими аннотациям. Думаю, в таком случае, его лучше обработать отдельно первым делом.

→ Ссылка
Автор решения: Alexandr

Если это кастомные аннотации, то соотвественно их можно расширить, например, добавив какие-нибудь аннотации, которые предоставят дополнительную информацию для построения структуры хранения методов и порядка их выполнения.

package com.somepackage;

import java.lang.annotation.*;
import java.lang.reflect.Method;
import java.util.*;
import java.util.stream.Collectors;

public class Main {

    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.ANNOTATION_TYPE})
    public @interface Ordered {
        int value() default 0;
    }

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    @Ordered
    public @interface SomeAnnotationA {
    }

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    @Ordered(value = 1)
    public @interface SomeAnnotationB {
    }

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    @Ordered(value = 2)
    public @interface SomeAnnotationC {
    }

    static class SomeClass {

        @SomeAnnotationB
        public void someMethodB() {
        }

        @SomeAnnotationC
        public void someMethodC() {
        }

        @SomeAnnotationA
        public void someMethodA() {
        }

    }

    public static void main(String[] args) {
        Map<Integer, List<Method>> map =
                Arrays.stream(SomeClass.class.getDeclaredMethods())
                        .collect(
                                Collectors.groupingBy(
                                        (Method m) -> Arrays.stream(m.getAnnotations())
                                                .map(a -> a.annotationType().getAnnotation(Ordered.class))
                                                .filter(Objects::nonNull)
                                                .map(Ordered::value)
                                                .max(Comparator.naturalOrder())
                                                .orElse(Integer.MAX_VALUE)));
        System.out.println(
                map.entrySet().stream()
                        .map(e -> e.getKey() + " -> " + e.getValue())
                        .collect(Collectors.joining(", ")));
    }

}
→ Ссылка