feat(MethodScanner): 添加方法扫描器与对应的方法匹配器 (Gitee #I6XUCF)

This commit is contained in:
huangchengxing
2023-05-09 01:24:04 +08:00
parent 90219696ec
commit 175ece5435
7 changed files with 2073 additions and 0 deletions

View File

@@ -0,0 +1,63 @@
package org.dromara.hutool.core.reflect.method;
import lombok.SneakyThrows;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import java.lang.reflect.Method;
/**
* test for {@link MethodMatcher}
*
* @author huangchengxing
*/
class MethodMatcherTest {
private MethodMatcher matchToString = (MethodMatcher)t -> "toString".equals(t.getName());
@SneakyThrows
@Test
void test() {
Method toString = Object.class.getDeclaredMethod("toString");
Assertions.assertTrue(matchToString.test(toString));
Method hashCode = Object.class.getDeclaredMethod("hashCode");
Assertions.assertFalse(matchToString.test(hashCode));
}
@SneakyThrows
@Test
void and() {
Method toString = Object.class.getDeclaredMethod("toString");
Assertions.assertTrue(matchToString.test(toString));
MethodMatcher newMatcher = matchToString.and(t -> t.getReturnType() == String.class);
Assertions.assertTrue(newMatcher.test(toString));
}
@SneakyThrows
@Test
void negate() {
Method toString = Object.class.getDeclaredMethod("toString");
Assertions.assertTrue(matchToString.test(toString));
MethodMatcher newMatcher = matchToString.negate();
Assertions.assertFalse(newMatcher.test(toString));
}
@SneakyThrows
@Test
void or() {
MethodMatcher newMatcher = matchToString.or(t -> "hashCode".equals(t.getName()));
Method toString = Object.class.getDeclaredMethod("toString");
Method hashCode = Object.class.getDeclaredMethod("hashCode");
Assertions.assertTrue(newMatcher.test(toString));
Assertions.assertTrue(newMatcher.test(hashCode));
}
@SneakyThrows
@Test
void inspect() {
Method toString = Object.class.getDeclaredMethod("toString");
Assertions.assertTrue(matchToString.inspect(toString));
Method hashCode = Object.class.getDeclaredMethod("hashCode");
Assertions.assertNull(matchToString.inspect(hashCode));
}
}

View File

@@ -0,0 +1,662 @@
package org.dromara.hutool.core.reflect.method;
import lombok.Getter;
import lombok.Setter;
import lombok.SneakyThrows;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Collection;
import java.util.List;
import java.util.Set;
/**
* test for {@link MethodMatcherUtils}
*
* @author huangchengxing
*/
class MethodMatcherUtilsTest {
private Method noneReturnNoArgs;
private Method noneReturnOneArgs;
private Method noneReturnTwoArgs;
private Method noneReturnTwoArgs2;
private Method returnNoArgs;
private Method returnOneArgs;
private Method returnTwoArgs;
@SneakyThrows
@BeforeEach
void init() {
this.noneReturnNoArgs = MethodMatcherUtilsTest.class.getDeclaredMethod("noneReturnNoArgs");
this.noneReturnOneArgs = MethodMatcherUtilsTest.class.getDeclaredMethod("noneReturnOneArgs", String.class);
this.noneReturnTwoArgs = MethodMatcherUtilsTest.class.getDeclaredMethod("noneReturnTwoArgs", String.class, List.class);
this.noneReturnTwoArgs2 = MethodMatcherUtilsTest.class.getDeclaredMethod("noneReturnTwoArgs", CharSequence.class, Collection.class);
this.returnNoArgs = MethodMatcherUtilsTest.class.getDeclaredMethod("returnNoArgs");
this.returnOneArgs = MethodMatcherUtilsTest.class.getDeclaredMethod("returnOneArgs", String.class);
this.returnTwoArgs = MethodMatcherUtilsTest.class.getDeclaredMethod("returnTwoArgs", String.class, List.class);
}
@Test
void testForName() {
MethodMatcher methodMatcher = MethodMatcherUtils.forName("noneReturnNoArgs");
Assertions.assertTrue(methodMatcher.test(noneReturnNoArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnOneArgs));
}
@Test
void forNameIgnoreCase() {
MethodMatcher methodMatcher = MethodMatcherUtils.forNameIgnoreCase("noneReturnNoArgs");
Assertions.assertTrue(methodMatcher.test(noneReturnNoArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnOneArgs));
// if name is upper case, it will be ignored
methodMatcher = MethodMatcherUtils.forNameIgnoreCase("NONERETURNNOARGS");
Assertions.assertTrue(methodMatcher.test(noneReturnNoArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnOneArgs));
}
@Test
void forNoneReturnType() {
MethodMatcher methodMatcher = MethodMatcherUtils.forNoneReturnType();
Assertions.assertTrue(methodMatcher.test(noneReturnNoArgs));
Assertions.assertTrue(methodMatcher.test(noneReturnOneArgs));
Assertions.assertTrue(methodMatcher.test(noneReturnTwoArgs));
Assertions.assertFalse(methodMatcher.test(returnNoArgs));
Assertions.assertFalse(methodMatcher.test(returnOneArgs));
Assertions.assertFalse(methodMatcher.test(returnTwoArgs));
}
@Test
void forReturnType() {
MethodMatcher methodMatcher = MethodMatcherUtils.forReturnType(Collection.class);
Assertions.assertFalse(methodMatcher.test(noneReturnNoArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnOneArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnTwoArgs));
Assertions.assertTrue(methodMatcher.test(returnNoArgs));
Assertions.assertTrue(methodMatcher.test(returnOneArgs));
Assertions.assertTrue(methodMatcher.test(returnTwoArgs));
}
@Test
void forStrictReturnType() {
MethodMatcher methodMatcher = MethodMatcherUtils.forStrictReturnType(Collection.class);
Assertions.assertFalse(methodMatcher.test(noneReturnNoArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnOneArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnTwoArgs));
Assertions.assertFalse(methodMatcher.test(returnNoArgs));
Assertions.assertFalse(methodMatcher.test(returnOneArgs));
Assertions.assertFalse(methodMatcher.test(returnTwoArgs));
// only match return type is strict equal to parameter type
methodMatcher = MethodMatcherUtils.forStrictReturnType(List.class);
Assertions.assertFalse(methodMatcher.test(noneReturnNoArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnOneArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnTwoArgs));
Assertions.assertTrue(methodMatcher.test(returnNoArgs));
Assertions.assertFalse(methodMatcher.test(returnOneArgs));
Assertions.assertTrue(methodMatcher.test(returnTwoArgs));
}
@Test
void forParameterCount() {
MethodMatcher methodMatcher = MethodMatcherUtils.forParameterCount(2);
Assertions.assertFalse(methodMatcher.test(noneReturnNoArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnOneArgs));
Assertions.assertTrue(methodMatcher.test(noneReturnTwoArgs));
}
@Test
void forMostSpecificParameterTypes() {
// match none args method
MethodMatcher methodMatcher = MethodMatcherUtils.forMostSpecificParameterTypes();
Assertions.assertFalse(methodMatcher.test(returnTwoArgs));
Assertions.assertTrue(methodMatcher.test(noneReturnNoArgs));
// match all args types
methodMatcher = MethodMatcherUtils.forMostSpecificParameterTypes(null, null);
Assertions.assertTrue(methodMatcher.test(returnTwoArgs));
Assertions.assertTrue(methodMatcher.test(noneReturnTwoArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnOneArgs));
// match first arg type
methodMatcher = MethodMatcherUtils.forMostSpecificParameterTypes(CharSequence.class, null);
Assertions.assertTrue(methodMatcher.test(returnTwoArgs));
Assertions.assertTrue(methodMatcher.test(noneReturnTwoArgs));
Assertions.assertFalse(methodMatcher.test(returnOneArgs));
// match second arg type
methodMatcher = MethodMatcherUtils.forMostSpecificParameterTypes(null, Collection.class);
Assertions.assertTrue(methodMatcher.test(returnTwoArgs));
Assertions.assertTrue(methodMatcher.test(noneReturnTwoArgs));
Assertions.assertFalse(methodMatcher.test(returnOneArgs));
// match two arg type
methodMatcher = MethodMatcherUtils.forMostSpecificParameterTypes(CharSequence.class, Collection.class);
Assertions.assertTrue(methodMatcher.test(returnTwoArgs));
Assertions.assertTrue(methodMatcher.test(noneReturnTwoArgs));
Assertions.assertFalse(methodMatcher.test(returnOneArgs));
}
@Test
void forMostSpecificStrictParameterTypes() {
// match none args method
MethodMatcher methodMatcher = MethodMatcherUtils.forMostSpecificStrictParameterTypes();
Assertions.assertFalse(methodMatcher.test(returnTwoArgs));
Assertions.assertTrue(methodMatcher.test(noneReturnNoArgs));
// match all args types
methodMatcher = MethodMatcherUtils.forMostSpecificStrictParameterTypes(null, null);
Assertions.assertTrue(methodMatcher.test(returnTwoArgs));
Assertions.assertTrue(methodMatcher.test(noneReturnTwoArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnOneArgs));
// match first arg type
methodMatcher = MethodMatcherUtils.forMostSpecificStrictParameterTypes(CharSequence.class, null);
Assertions.assertFalse(methodMatcher.test(returnTwoArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnTwoArgs));
Assertions.assertFalse(methodMatcher.test(returnOneArgs));
methodMatcher = MethodMatcherUtils.forMostSpecificStrictParameterTypes(String.class, null);
Assertions.assertTrue(methodMatcher.test(returnTwoArgs));
Assertions.assertTrue(methodMatcher.test(noneReturnTwoArgs));
Assertions.assertFalse(methodMatcher.test(returnOneArgs));
// match second arg type
methodMatcher = MethodMatcherUtils.forMostSpecificStrictParameterTypes(null, Collection.class);
Assertions.assertFalse(methodMatcher.test(returnTwoArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnTwoArgs));
Assertions.assertFalse(methodMatcher.test(returnOneArgs));
// match two arg type
methodMatcher = MethodMatcherUtils.forMostSpecificStrictParameterTypes(CharSequence.class, Collection.class);
Assertions.assertFalse(methodMatcher.test(returnTwoArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnTwoArgs));
Assertions.assertFalse(methodMatcher.test(returnOneArgs));
}
@Test
void forParameterTypes() {
MethodMatcher methodMatcher = MethodMatcherUtils.forParameterTypes();
Assertions.assertTrue(methodMatcher.test(noneReturnNoArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnOneArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnTwoArgs));
Assertions.assertTrue(methodMatcher.test(returnNoArgs));
Assertions.assertFalse(methodMatcher.test(returnOneArgs));
Assertions.assertFalse(methodMatcher.test(returnTwoArgs));
// match parameter types is empty
methodMatcher = MethodMatcherUtils.forParameterTypes(CharSequence.class, Collection.class);
Assertions.assertFalse(methodMatcher.test(noneReturnNoArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnOneArgs));
Assertions.assertTrue(methodMatcher.test(noneReturnTwoArgs));
Assertions.assertFalse(methodMatcher.test(returnNoArgs));
Assertions.assertFalse(methodMatcher.test(returnOneArgs));
Assertions.assertTrue(methodMatcher.test(returnTwoArgs));
}
@Test
void forStrictParameterTypes() {
MethodMatcher methodMatcher = MethodMatcherUtils.forStrictParameterTypes();
Assertions.assertTrue(methodMatcher.test(noneReturnNoArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnOneArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnTwoArgs));
Assertions.assertTrue(methodMatcher.test(returnNoArgs));
Assertions.assertFalse(methodMatcher.test(returnOneArgs));
Assertions.assertFalse(methodMatcher.test(returnTwoArgs));
// cannot match assignable parameter types
methodMatcher = MethodMatcherUtils.forStrictParameterTypes(CharSequence.class, Collection.class);
Assertions.assertFalse(methodMatcher.test(noneReturnNoArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnOneArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnTwoArgs));
Assertions.assertFalse(methodMatcher.test(returnNoArgs));
Assertions.assertFalse(methodMatcher.test(returnOneArgs));
Assertions.assertFalse(methodMatcher.test(returnTwoArgs));
// only match parameter types is strict equal to parameter type
methodMatcher = MethodMatcherUtils.forStrictParameterTypes(String.class, List.class);
Assertions.assertFalse(methodMatcher.test(noneReturnNoArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnOneArgs));
Assertions.assertTrue(methodMatcher.test(noneReturnTwoArgs));
Assertions.assertFalse(methodMatcher.test(returnNoArgs));
Assertions.assertFalse(methodMatcher.test(returnOneArgs));
Assertions.assertTrue(methodMatcher.test(returnTwoArgs));
}
@Test
void noneMatch() {
MethodMatcher methodMatcher = MethodMatcherUtils.noneMatch();
Assertions.assertTrue(methodMatcher.test(noneReturnNoArgs));
Assertions.assertTrue(methodMatcher.test(noneReturnOneArgs));
Assertions.assertTrue(methodMatcher.test(noneReturnTwoArgs));
Assertions.assertTrue(methodMatcher.test(returnNoArgs));
Assertions.assertTrue(methodMatcher.test(returnOneArgs));
Assertions.assertTrue(methodMatcher.test(returnTwoArgs));
// combine with other matchers
methodMatcher = MethodMatcherUtils.noneMatch(
MethodMatcherUtils.forName("noneReturnNoArgs"),
MethodMatcherUtils.forReturnType(Collection.class)
);
Assertions.assertFalse(methodMatcher.test(noneReturnNoArgs));
Assertions.assertTrue(methodMatcher.test(noneReturnOneArgs));
}
@Test
void anyMatch() {
MethodMatcher methodMatcher = MethodMatcherUtils.anyMatch();
Assertions.assertFalse(methodMatcher.test(noneReturnNoArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnOneArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnTwoArgs));
Assertions.assertFalse(methodMatcher.test(returnNoArgs));
Assertions.assertFalse(methodMatcher.test(returnOneArgs));
Assertions.assertFalse(methodMatcher.test(returnTwoArgs));
// combine with other matchers
methodMatcher = MethodMatcherUtils.anyMatch(
MethodMatcherUtils.forName("noneReturnNoArgs"),
MethodMatcherUtils.forReturnType(Collection.class)
);
Assertions.assertTrue(methodMatcher.test(returnNoArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnOneArgs));
Assertions.assertTrue(methodMatcher.test(returnTwoArgs));
}
@Test
void allMatch() {
MethodMatcher methodMatcher = MethodMatcherUtils.allMatch();
Assertions.assertTrue(methodMatcher.test(noneReturnNoArgs));
Assertions.assertTrue(methodMatcher.test(noneReturnOneArgs));
Assertions.assertTrue(methodMatcher.test(noneReturnTwoArgs));
Assertions.assertTrue(methodMatcher.test(returnNoArgs));
Assertions.assertTrue(methodMatcher.test(returnOneArgs));
Assertions.assertTrue(methodMatcher.test(returnTwoArgs));
// combine with other matchers
methodMatcher = MethodMatcherUtils.allMatch(
MethodMatcherUtils.forName("noneReturnNoArgs"),
MethodMatcherUtils.forReturnType(Collection.class)
);
Assertions.assertFalse(methodMatcher.test(noneReturnNoArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnOneArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnTwoArgs));
Assertions.assertFalse(methodMatcher.test(returnNoArgs));
Assertions.assertFalse(methodMatcher.test(returnOneArgs));
Assertions.assertFalse(methodMatcher.test(returnTwoArgs));
}
@Test
void isPublic() {
MethodMatcher methodMatcher = MethodMatcherUtils.isPublic();
Assertions.assertFalse(methodMatcher.test(noneReturnNoArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnOneArgs));
Assertions.assertTrue(methodMatcher.test(noneReturnTwoArgs));
Assertions.assertTrue(methodMatcher.test(returnNoArgs));
Assertions.assertTrue(methodMatcher.test(returnOneArgs));
Assertions.assertTrue(methodMatcher.test(returnTwoArgs));
}
@Test
void isStatic() {
MethodMatcher methodMatcher = MethodMatcherUtils.isStatic();
Assertions.assertFalse(methodMatcher.test(noneReturnNoArgs));
Assertions.assertTrue(methodMatcher.test(noneReturnOneArgs));
Assertions.assertTrue(methodMatcher.test(noneReturnTwoArgs));
Assertions.assertFalse(methodMatcher.test(returnNoArgs));
Assertions.assertFalse(methodMatcher.test(returnOneArgs));
Assertions.assertFalse(methodMatcher.test(returnTwoArgs));
}
@Test
void isPublicStatic() {
MethodMatcher methodMatcher = MethodMatcherUtils.isPublicStatic();
Assertions.assertFalse(methodMatcher.test(noneReturnNoArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnOneArgs));
Assertions.assertTrue(methodMatcher.test(noneReturnTwoArgs));
Assertions.assertFalse(methodMatcher.test(returnNoArgs));
Assertions.assertFalse(methodMatcher.test(returnOneArgs));
Assertions.assertFalse(methodMatcher.test(returnTwoArgs));
}
@Test
void forModifiers() {
MethodMatcher methodMatcher = MethodMatcherUtils.forModifiers(Modifier.PUBLIC, Modifier.STATIC);
Assertions.assertFalse(methodMatcher.test(noneReturnNoArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnOneArgs));
Assertions.assertTrue(methodMatcher.test(noneReturnTwoArgs));
Assertions.assertFalse(methodMatcher.test(returnNoArgs));
Assertions.assertFalse(methodMatcher.test(returnOneArgs));
Assertions.assertFalse(methodMatcher.test(returnTwoArgs));
}
@Test
void forNameAndParameterTypes() {
MethodMatcher methodMatcher = MethodMatcherUtils.forNameAndParameterTypes("noneReturnTwoArgs", CharSequence.class, List.class);
Assertions.assertFalse(methodMatcher.test(noneReturnNoArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnOneArgs));
Assertions.assertTrue(methodMatcher.test(noneReturnTwoArgs));
Assertions.assertFalse(methodMatcher.test(returnNoArgs));
Assertions.assertFalse(methodMatcher.test(returnOneArgs));
Assertions.assertFalse(methodMatcher.test(returnTwoArgs));
}
@Test
void forNameAndStrictParameterTypes() {
MethodMatcher methodMatcher = MethodMatcherUtils.forNameAndStrictParameterTypes("noneReturnTwoArgs", CharSequence.class, List.class);
Assertions.assertFalse(methodMatcher.test(noneReturnNoArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnOneArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnTwoArgs));
Assertions.assertFalse(methodMatcher.test(returnNoArgs));
Assertions.assertFalse(methodMatcher.test(returnOneArgs));
Assertions.assertFalse(methodMatcher.test(returnTwoArgs));
methodMatcher = MethodMatcherUtils.forNameAndStrictParameterTypes("returnTwoArgs", String.class, List.class);
Assertions.assertFalse(methodMatcher.test(noneReturnNoArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnOneArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnTwoArgs));
Assertions.assertFalse(methodMatcher.test(returnNoArgs));
Assertions.assertFalse(methodMatcher.test(returnOneArgs));
Assertions.assertTrue(methodMatcher.test(returnTwoArgs));
}
@Test
void forNameIgnoreCaseAndParameterTypes() {
MethodMatcher methodMatcher = MethodMatcherUtils.forNameIgnoreCaseAndParameterTypes("NONEReturnTWOArgs", CharSequence.class, List.class);
Assertions.assertFalse(methodMatcher.test(noneReturnNoArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnOneArgs));
Assertions.assertTrue(methodMatcher.test(noneReturnTwoArgs));
Assertions.assertFalse(methodMatcher.test(returnNoArgs));
Assertions.assertFalse(methodMatcher.test(returnOneArgs));
Assertions.assertFalse(methodMatcher.test(returnTwoArgs));
methodMatcher = MethodMatcherUtils.forNameIgnoreCaseAndParameterTypes("ReturnTWOArgs", String.class, List.class);
Assertions.assertFalse(methodMatcher.test(noneReturnNoArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnOneArgs));
Assertions.assertTrue(methodMatcher.test(noneReturnTwoArgs));
Assertions.assertFalse(methodMatcher.test(returnNoArgs));
Assertions.assertFalse(methodMatcher.test(returnOneArgs));
Assertions.assertTrue(methodMatcher.test(returnTwoArgs));
}
@Test
void forNameIgnoreCaseAndStrictParameterTypes() {
MethodMatcher methodMatcher = MethodMatcherUtils.forNameIgnoreCaseAndStrictParameterTypes("NONEReturnTWOArgs", CharSequence.class, List.class);
Assertions.assertFalse(methodMatcher.test(noneReturnNoArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnOneArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnTwoArgs));
Assertions.assertFalse(methodMatcher.test(returnNoArgs));
Assertions.assertFalse(methodMatcher.test(returnOneArgs));
Assertions.assertFalse(methodMatcher.test(returnTwoArgs));
methodMatcher = MethodMatcherUtils.forNameIgnoreCaseAndStrictParameterTypes("ReturnTWOArgs", String.class, List.class);
Assertions.assertFalse(methodMatcher.test(noneReturnNoArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnOneArgs));
Assertions.assertTrue(methodMatcher.test(noneReturnTwoArgs));
Assertions.assertFalse(methodMatcher.test(returnNoArgs));
Assertions.assertFalse(methodMatcher.test(returnOneArgs));
Assertions.assertTrue(methodMatcher.test(returnTwoArgs));
}
@Test
void forStrictMethodSignature() {
MethodMatcher methodMatcher = MethodMatcherUtils.forStrictMethodSignature("noneReturnTwoArgs", null, CharSequence.class, Collection.class);
Assertions.assertFalse(methodMatcher.test(noneReturnNoArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnOneArgs));
Assertions.assertTrue(methodMatcher.test(noneReturnTwoArgs2));
Assertions.assertFalse(methodMatcher.test(returnNoArgs));
Assertions.assertFalse(methodMatcher.test(returnOneArgs));
Assertions.assertFalse(methodMatcher.test(returnTwoArgs));
methodMatcher = MethodMatcherUtils.forStrictMethodSignature("noneReturnTwoArgs", null, String.class, List.class);
Assertions.assertFalse(methodMatcher.test(noneReturnNoArgs));
Assertions.assertTrue(methodMatcher.test(noneReturnTwoArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnTwoArgs2));
Assertions.assertFalse(methodMatcher.test(returnNoArgs));
Assertions.assertFalse(methodMatcher.test(returnOneArgs));
Assertions.assertFalse(methodMatcher.test(returnTwoArgs));
}
@Test
void forStrictMethodSignatureWithMethod() {
MethodMatcher methodMatcher = MethodMatcherUtils.forStrictMethodSignature(noneReturnTwoArgs);
Assertions.assertFalse(methodMatcher.test(noneReturnNoArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnOneArgs));
Assertions.assertTrue(methodMatcher.test(noneReturnTwoArgs));
Assertions.assertFalse(methodMatcher.test(returnNoArgs));
Assertions.assertFalse(methodMatcher.test(returnOneArgs));
Assertions.assertFalse(methodMatcher.test(returnTwoArgs));
methodMatcher = MethodMatcherUtils.forStrictMethodSignature(returnTwoArgs);
Assertions.assertFalse(methodMatcher.test(noneReturnNoArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnOneArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnTwoArgs));
Assertions.assertFalse(methodMatcher.test(returnNoArgs));
Assertions.assertFalse(methodMatcher.test(returnOneArgs));
Assertions.assertTrue(methodMatcher.test(returnTwoArgs));
}
@Test
void forMethodSignatureWithMethod() {
MethodMatcher methodMatcher = MethodMatcherUtils.forMethodSignature(noneReturnTwoArgs2);
Assertions.assertFalse(methodMatcher.test(noneReturnNoArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnOneArgs));
Assertions.assertTrue(methodMatcher.test(noneReturnTwoArgs));
Assertions.assertFalse(methodMatcher.test(returnNoArgs));
Assertions.assertFalse(methodMatcher.test(returnOneArgs));
Assertions.assertFalse(methodMatcher.test(returnTwoArgs));
Assertions.assertTrue(methodMatcher.test(noneReturnTwoArgs2));
}
@Test
void forMethodSignature() {
MethodMatcher methodMatcher = MethodMatcherUtils.forMethodSignature(
"noneReturnTwoArgs", null, CharSequence.class, Collection.class
);
Assertions.assertFalse(methodMatcher.test(noneReturnNoArgs));
Assertions.assertFalse(methodMatcher.test(noneReturnOneArgs));
Assertions.assertTrue(methodMatcher.test(noneReturnTwoArgs));
Assertions.assertFalse(methodMatcher.test(returnNoArgs));
Assertions.assertFalse(methodMatcher.test(returnOneArgs));
Assertions.assertFalse(methodMatcher.test(returnTwoArgs));
Assertions.assertTrue(methodMatcher.test(noneReturnTwoArgs2));
}
@Test
@SneakyThrows
void forGetterMethodWithField() {
Field nameField = Foo.class.getDeclaredField("name");
MethodMatcher methodMatcher = MethodMatcherUtils.forGetterMethod(nameField);
Method getName = Foo.class.getMethod("getName");
Assertions.assertTrue(methodMatcher.test(getName));
Field flagField = Foo.class.getDeclaredField("flag");
methodMatcher = MethodMatcherUtils.forGetterMethod(flagField);
Method isFlag = Foo.class.getMethod("isFlag");
Assertions.assertTrue(methodMatcher.test(isFlag));
Field objectField = Foo.class.getDeclaredField("object");
methodMatcher = MethodMatcherUtils.forGetterMethod(objectField);
Method object = Foo.class.getMethod("object");
Assertions.assertTrue(methodMatcher.test(object));
}
@Test
@SneakyThrows
void forGetterMethod() {
MethodMatcher methodMatcher = MethodMatcherUtils.forGetterMethod("name", String.class);
Method getName = Foo.class.getMethod("getName");
Assertions.assertTrue(methodMatcher.test(getName));
methodMatcher = MethodMatcherUtils.forGetterMethod("flag", boolean.class);
Method isFlag = Foo.class.getMethod("isFlag");
Assertions.assertTrue(methodMatcher.test(isFlag));
methodMatcher = MethodMatcherUtils.forGetterMethod("object", Object.class);
Method object = Foo.class.getMethod("object");
Assertions.assertTrue(methodMatcher.test(object));
}
@Test
@SneakyThrows
void forSetterMethodWithField() {
Field nameField = Foo.class.getDeclaredField("name");
MethodMatcher methodMatcher = MethodMatcherUtils.forSetterMethod(nameField);
Method setName = Foo.class.getMethod("setName", String.class);
Assertions.assertTrue(methodMatcher.test(setName));
Field flagField = Foo.class.getDeclaredField("flag");
methodMatcher = MethodMatcherUtils.forSetterMethod(flagField);
Method setFlag = Foo.class.getMethod("setFlag", boolean.class);
Assertions.assertTrue(methodMatcher.test(setFlag));
Field objectField = Foo.class.getDeclaredField("object");
methodMatcher = MethodMatcherUtils.forSetterMethod(objectField);
Method object = Foo.class.getMethod("object", Object.class);
Assertions.assertTrue(methodMatcher.test(object));
}
@Test
@SneakyThrows
void forSetterMethod() {
MethodMatcher methodMatcher = MethodMatcherUtils.forSetterMethod("name", String.class);
Method setName = Foo.class.getMethod("setName", String.class);
Assertions.assertTrue(methodMatcher.test(setName));
methodMatcher = MethodMatcherUtils.forSetterMethod("flag", boolean.class);
Method setFlag = Foo.class.getMethod("setFlag", boolean.class);
Assertions.assertTrue(methodMatcher.test(setFlag));
methodMatcher = MethodMatcherUtils.forSetterMethod("object", Object.class);
Method object = Foo.class.getMethod("object", Object.class);
Assertions.assertTrue(methodMatcher.test(object));
}
@Test
@SneakyThrows
void hasDeclaredAnnotation() {
MethodMatcher methodMatcher = MethodMatcherUtils.hasDeclaredAnnotation(GrandParentAnnotation.class);
Assertions.assertFalse(methodMatcher.test(AnnotatedClass.class.getDeclaredMethod("annotatedByChildAnnotation")));
Assertions.assertFalse(methodMatcher.test(AnnotatedClass.class.getDeclaredMethod("annotatedByParentAnnotation")));
Assertions.assertTrue(methodMatcher.test(AnnotatedClass.class.getDeclaredMethod("annotatedByGrandParentAnnotation")));
Assertions.assertFalse(methodMatcher.test(AnnotatedClass.class.getDeclaredMethod("noneAnnotated")));
}
@Test
@SneakyThrows
void hasAnnotation() {
MethodMatcher methodMatcher = MethodMatcherUtils.hasAnnotation(GrandParentAnnotation.class);
Assertions.assertTrue(methodMatcher.test(AnnotatedClass.class.getDeclaredMethod("annotatedByChildAnnotation")));
Assertions.assertTrue(methodMatcher.test(AnnotatedClass.class.getDeclaredMethod("annotatedByParentAnnotation")));
Assertions.assertTrue(methodMatcher.test(AnnotatedClass.class.getDeclaredMethod("annotatedByGrandParentAnnotation")));
Assertions.assertFalse(methodMatcher.test(AnnotatedClass.class.getDeclaredMethod("noneAnnotated")));
methodMatcher = MethodMatcherUtils.hasAnnotation(ParentAnnotation.class);
Assertions.assertTrue(methodMatcher.test(AnnotatedClass.class.getDeclaredMethod("annotatedByChildAnnotation")));
Assertions.assertTrue(methodMatcher.test(AnnotatedClass.class.getDeclaredMethod("annotatedByParentAnnotation")));
Assertions.assertFalse(methodMatcher.test(AnnotatedClass.class.getDeclaredMethod("annotatedByGrandParentAnnotation")));
Assertions.assertFalse(methodMatcher.test(AnnotatedClass.class.getDeclaredMethod("noneAnnotated")));
}
@Test
@SneakyThrows
void hasAnnotationOnDeclaringClass() {
MethodMatcher methodMatcher = MethodMatcherUtils.hasAnnotationOnDeclaringClass(GrandParentAnnotation.class);
Assertions.assertTrue(methodMatcher.test(AnnotatedClass.class.getDeclaredMethod("annotatedByChildAnnotation")));
Assertions.assertTrue(methodMatcher.test(AnnotatedClass.class.getDeclaredMethod("annotatedByParentAnnotation")));
Assertions.assertTrue(methodMatcher.test(AnnotatedClass.class.getDeclaredMethod("annotatedByGrandParentAnnotation")));
Assertions.assertTrue(methodMatcher.test(AnnotatedClass.class.getDeclaredMethod("noneAnnotated")));
methodMatcher = MethodMatcherUtils.hasAnnotationOnDeclaringClass(ParentAnnotation.class);
Assertions.assertTrue(methodMatcher.test(AnnotatedClass.class.getDeclaredMethod("annotatedByChildAnnotation")));
Assertions.assertTrue(methodMatcher.test(AnnotatedClass.class.getDeclaredMethod("annotatedByParentAnnotation")));
Assertions.assertTrue(methodMatcher.test(AnnotatedClass.class.getDeclaredMethod("annotatedByGrandParentAnnotation")));
Assertions.assertTrue(methodMatcher.test(AnnotatedClass.class.getDeclaredMethod("noneAnnotated")));
methodMatcher = MethodMatcherUtils.hasAnnotationOnDeclaringClass(ChildAnnotation.class);
Assertions.assertFalse(methodMatcher.test(AnnotatedClass.class.getDeclaredMethod("annotatedByChildAnnotation")));
Assertions.assertFalse(methodMatcher.test(AnnotatedClass.class.getDeclaredMethod("annotatedByParentAnnotation")));
Assertions.assertFalse(methodMatcher.test(AnnotatedClass.class.getDeclaredMethod("annotatedByGrandParentAnnotation")));
Assertions.assertFalse(methodMatcher.test(AnnotatedClass.class.getDeclaredMethod("noneAnnotated")));
}
@Test
@SneakyThrows
void hasAnnotationOnMethodOrDeclaringClass() {
MethodMatcher methodMatcher = MethodMatcherUtils.hasAnnotationOnMethodOrDeclaringClass(GrandParentAnnotation.class);
Assertions.assertTrue(methodMatcher.test(AnnotatedClass.class.getDeclaredMethod("annotatedByChildAnnotation")));
Assertions.assertTrue(methodMatcher.test(AnnotatedClass.class.getDeclaredMethod("annotatedByParentAnnotation")));
Assertions.assertTrue(methodMatcher.test(AnnotatedClass.class.getDeclaredMethod("annotatedByGrandParentAnnotation")));
Assertions.assertTrue(methodMatcher.test(AnnotatedClass.class.getDeclaredMethod("noneAnnotated")));
methodMatcher = MethodMatcherUtils.hasAnnotationOnMethodOrDeclaringClass(ParentAnnotation.class);
Assertions.assertTrue(methodMatcher.test(AnnotatedClass.class.getDeclaredMethod("annotatedByChildAnnotation")));
Assertions.assertTrue(methodMatcher.test(AnnotatedClass.class.getDeclaredMethod("annotatedByParentAnnotation")));
Assertions.assertTrue(methodMatcher.test(AnnotatedClass.class.getDeclaredMethod("annotatedByGrandParentAnnotation")));
Assertions.assertTrue(methodMatcher.test(AnnotatedClass.class.getDeclaredMethod("noneAnnotated")));
methodMatcher = MethodMatcherUtils.hasAnnotationOnMethodOrDeclaringClass(ChildAnnotation.class);
Assertions.assertTrue(methodMatcher.test(AnnotatedClass.class.getDeclaredMethod("annotatedByChildAnnotation")));
Assertions.assertFalse(methodMatcher.test(AnnotatedClass.class.getDeclaredMethod("annotatedByParentAnnotation")));
Assertions.assertFalse(methodMatcher.test(AnnotatedClass.class.getDeclaredMethod("annotatedByGrandParentAnnotation")));
Assertions.assertFalse(methodMatcher.test(AnnotatedClass.class.getDeclaredMethod("noneAnnotated")));
}
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
private @interface GrandParentAnnotation {}
@GrandParentAnnotation
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
private @interface ParentAnnotation {}
@ParentAnnotation
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
private @interface ChildAnnotation {}
@ParentAnnotation
private static class AnnotatedClass {
@ChildAnnotation
private void annotatedByChildAnnotation() { }
@ParentAnnotation
private static void annotatedByParentAnnotation() { }
@GrandParentAnnotation
public static void annotatedByGrandParentAnnotation() { }
public static void noneAnnotated() { }
}
private static class Foo {
@Setter
@Getter
private String name;
@Setter
@Getter
private boolean flag;
private Object object;
public void setName(String name, Void none) { }
public Object object() {
return object;
}
public Foo object(Object object) {
this.object = object;
return this;
}
}
private void noneReturnNoArgs() { }
private static void noneReturnOneArgs(String arg1) { }
public static void noneReturnTwoArgs(String arg1, List<String> stringList) { }
public static void noneReturnTwoArgs(CharSequence arg1, Collection<String> stringList) { }
public List<String> returnNoArgs() { return null; }
public Set<String> returnOneArgs(String arg1) { return null; }
public List<String> returnTwoArgs(String arg1, List<String> stringList) { return null; }
}

View File

@@ -0,0 +1,279 @@
package org.dromara.hutool.core.reflect.method;
import lombok.SneakyThrows;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
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.Map;
import java.util.Set;
import java.util.stream.Stream;
/**
* test for {@link MethodScanner}
*
* @author huangchengxing
*/
class MethodScannerTest {
@Test
void testGetMethods() {
Assertions.assertEquals(0, MethodScanner.getMethods(null).length);
Method[] actual = MethodScanner.getMethods(Child.class);
Assertions.assertSame(actual, MethodScanner.getMethods(Child.class));
Method[] expected = Child.class.getMethods();
Assertions.assertArrayEquals(expected, actual);
}
@Test
void testGetDeclaredMethods() {
Assertions.assertEquals(0, MethodScanner.getDeclaredMethods(null).length);
Method[] actual = MethodScanner.getDeclaredMethods(Child.class);
Assertions.assertSame(actual, MethodScanner.getDeclaredMethods(Child.class));
Method[] expected = Child.class.getDeclaredMethods();
Assertions.assertArrayEquals(expected, actual);
}
@Test
void testGetAllMethods() {
Assertions.assertEquals(0, MethodScanner.getAllMethods(null).length);
Method[] actual = MethodScanner.getAllMethods(Child.class);
// get declared method from child、parent、grandparent
Method[] expected = Stream.of(Child.class, Parent.class, Interface.class, Object.class)
.flatMap(c -> Stream.of(MethodScanner.getDeclaredMethods(c)))
.toArray(Method[]::new);
Assertions.assertArrayEquals(expected, actual);
}
@Test
void testClearCaches() {
Method[] declaredMethods = MethodScanner.getDeclaredMethods(Child.class);
Assertions.assertSame(declaredMethods, MethodScanner.getDeclaredMethods(Child.class));
Method[] methods = MethodScanner.getMethods(Child.class);
Assertions.assertSame(methods, MethodScanner.getMethods(Child.class));
// clear method cache
MethodScanner.clearCaches();
Assertions.assertNotSame(declaredMethods, MethodScanner.getDeclaredMethods(Child.class));
Assertions.assertNotSame(methods, MethodScanner.getMethods(Child.class));
}
@SneakyThrows
@Test
void testFindWithMetadataFromSpecificMethods() {
Assertions.assertTrue(MethodScanner.findWithMetadataFromSpecificMethods(null, m -> m.getAnnotation(Annotation.class)).isEmpty());
Method[] methods = MethodScanner.getMethods(Child.class);
Map<Method, Annotation> actual = MethodScanner.findWithMetadataFromSpecificMethods(methods, m -> m.getAnnotation(Annotation.class));
Assertions.assertEquals(1, actual.size());
// check method
Method expectedMethod = Parent.class.getDeclaredMethod("oneArgMethod", String.class);
Assertions.assertTrue(actual.containsKey(expectedMethod));
// check annotation
Annotation expectedAnnotation = expectedMethod.getAnnotation(Annotation.class);
Assertions.assertEquals(expectedAnnotation, actual.get(expectedMethod));
}
@SneakyThrows
@Test
void testFindFromSpecificMethods() {
Method[] methods = MethodScanner.getMethods(Child.class);
Set<Method> actual = MethodScanner.findFromSpecificMethods(methods, m -> m.getAnnotation(Annotation.class));
Assertions.assertEquals(1, actual.size());
// check method
Method expectedMethod = Parent.class.getDeclaredMethod("oneArgMethod", String.class);
Assertions.assertTrue(actual.contains(expectedMethod));
}
@SneakyThrows
@Test
void testGetWithMetadataFromSpecificMethods() {
// find first oneArgMethod method
Method[] methods = MethodScanner.getMethods(Child.class);
Map.Entry<Method, Boolean> actual = MethodScanner.getWithMetadataFromSpecificMethods(methods, MethodMatcherUtils.forName("oneArgMethod"));
Assertions.assertNotNull(actual);
Method expectedMethod = Parent.class.getDeclaredMethod("oneArgMethod", String.class);
Assertions.assertEquals(expectedMethod, actual.getKey());
Assertions.assertTrue(actual.getValue());
}
@SneakyThrows
@Test
void testGetFromSpecificMethods() {
// find first oneArgMethod method
Method[] methods = MethodScanner.getMethods(Child.class);
Method actual = MethodScanner.getFromSpecificMethods(methods, MethodMatcherUtils.forName("oneArgMethod"));
Method expectedMethod = Parent.class.getDeclaredMethod("oneArgMethod", String.class);
Assertions.assertEquals(expectedMethod, actual);
}
@SneakyThrows
@Test
void testFindWithMetadataFromMethods() {
Map<Method, Annotation> actual = MethodScanner.findWithMetadataFromMethods(Child.class, m -> m.getAnnotation(Annotation.class));
Assertions.assertEquals(1, actual.size());
// check method
Method expectedMethod = Parent.class.getDeclaredMethod("oneArgMethod", String.class);
Assertions.assertTrue(actual.containsKey(expectedMethod));
// check annotation
Annotation expectedAnnotation = expectedMethod.getAnnotation(Annotation.class);
Assertions.assertEquals(expectedAnnotation, actual.get(expectedMethod));
}
@SneakyThrows
@Test
void testFindFromMethods() {
Set<Method> actual = MethodScanner.findFromMethods(Child.class, m -> m.getAnnotation(Annotation.class));
Assertions.assertEquals(1, actual.size());
// check method
Method expectedMethod = Parent.class.getDeclaredMethod("oneArgMethod", String.class);
Assertions.assertTrue(actual.contains(expectedMethod));
}
@SneakyThrows
@Test
void testGetWithMetadataFromMethods() {
Map.Entry<Method, Annotation> actual = MethodScanner.getWithMetadataFromMethods(Child.class, m -> m.getAnnotation(Annotation.class));
Assertions.assertNotNull(actual);
Method expectedMethod = Parent.class.getDeclaredMethod("oneArgMethod", String.class);
Assertions.assertEquals(expectedMethod, actual.getKey());
Annotation expectedAnnotation = expectedMethod.getAnnotation(Annotation.class);
Assertions.assertEquals(expectedAnnotation, actual.getValue());
}
@SneakyThrows
@Test
void testGetFromMethods() {
Method actual = MethodScanner.getFromMethods(Child.class, m -> m.getAnnotation(Annotation.class));
Method expectedMethod = Parent.class.getDeclaredMethod("oneArgMethod", String.class);
Assertions.assertEquals(expectedMethod, actual);
}
@SneakyThrows
@Test
void testFindWithMetadataFromDeclaredMethods() {
Map<Method, Annotation> actual = MethodScanner.findWithMetadataFromDeclaredMethods(Parent.class, m -> m.getAnnotation(Annotation.class));
Assertions.assertEquals(1, actual.size());
// check method
Method expectedMethod = Parent.class.getDeclaredMethod("oneArgMethod", String.class);
Assertions.assertTrue(actual.containsKey(expectedMethod));
// check annotation
Annotation expectedAnnotation = expectedMethod.getAnnotation(Annotation.class);
Assertions.assertEquals(expectedAnnotation, actual.get(expectedMethod));
}
@SneakyThrows
@Test
void testFindFromDeclaredMethods() {
Set<Method> actual = MethodScanner.findFromDeclaredMethods(Parent.class, m -> m.getAnnotation(Annotation.class));
Assertions.assertEquals(1, actual.size());
// check method
Method expectedMethod = Parent.class.getDeclaredMethod("oneArgMethod", String.class);
Assertions.assertTrue(actual.contains(expectedMethod));
}
@SneakyThrows
@Test
void testGetWithMetadataFromDeclaredMethods() {
Map.Entry<Method, Annotation> actual = MethodScanner.getWithMetadataFromDeclaredMethods(Parent.class, m -> m.getAnnotation(Annotation.class));
Assertions.assertNotNull(actual);
Method expectedMethod = Parent.class.getDeclaredMethod("oneArgMethod", String.class);
Assertions.assertEquals(expectedMethod, actual.getKey());
Annotation expectedAnnotation = expectedMethod.getAnnotation(Annotation.class);
Assertions.assertEquals(expectedAnnotation, actual.getValue());
}
@SneakyThrows
@Test
void testGetFromDeclaredMethods() {
Method actual = MethodScanner.getFromDeclaredMethods(Parent.class, m -> m.getAnnotation(Annotation.class));
Method expectedMethod = Parent.class.getDeclaredMethod("oneArgMethod", String.class);
Assertions.assertEquals(expectedMethod, actual);
}
@SneakyThrows
@Test
void testFindWithMetadataFromAllMethods() {
Map<Method, Annotation> actual = MethodScanner.findWithMetadataFromAllMethods(Child.class, m -> m.getAnnotation(Annotation.class));
Assertions.assertEquals(1, actual.size());
// check method
Method expectedMethod = Parent.class.getDeclaredMethod("oneArgMethod", String.class);
Assertions.assertTrue(actual.containsKey(expectedMethod));
// check annotation
Annotation expectedAnnotation = expectedMethod.getAnnotation(Annotation.class);
Assertions.assertEquals(expectedAnnotation, actual.get(expectedMethod));
}
@SneakyThrows
@Test
void testFindFromAllMethods() {
Set<Method> actual = MethodScanner.findFromAllMethods(Child.class, m -> m.getAnnotation(Annotation.class));
Assertions.assertEquals(1, actual.size());
// check method
Method expectedMethod = Parent.class.getDeclaredMethod("oneArgMethod", String.class);
Assertions.assertTrue(actual.contains(expectedMethod));
}
@SneakyThrows
@Test
void testGetWithMetadataFromAllMethods() {
Assertions.assertNull(MethodScanner.getWithMetadataFromAllMethods(Child.class, m -> m.getAnnotation(Deprecated.class)));
Map.Entry<Method, Annotation> actual = MethodScanner.getWithMetadataFromAllMethods(Child.class, m -> m.getAnnotation(Annotation.class));
Assertions.assertNotNull(actual);
Method expectedMethod = Parent.class.getDeclaredMethod("oneArgMethod", String.class);
Assertions.assertEquals(expectedMethod, actual.getKey());
Annotation expectedAnnotation = expectedMethod.getAnnotation(Annotation.class);
Assertions.assertEquals(expectedAnnotation, actual.getValue());
}
@SneakyThrows
@Test
void testGetFromAllMethods() {
Method actual = MethodScanner.getFromAllMethods(Child.class, m -> m.getAnnotation(Annotation.class));
Method expectedMethod = Parent.class.getDeclaredMethod("oneArgMethod", String.class);
Assertions.assertEquals(expectedMethod, actual);
}
@Target({ElementType.METHOD, ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Annotation {
String value() default "default";
}
@Annotation("Interface")
public interface Interface {
static void staticMethod() {
}
void noneArgMethod();
void oneArgMethod(String arg);
}
public static class Parent implements Interface {
@Override
public void noneArgMethod() { }
@Annotation("oneArgMethod")
@Override
public void oneArgMethod(String arg) { }
}
public static class Child extends Parent implements Interface {
}
}