Method详解

Method 提供关于类或接口上单独某个方法(以及如何访问该方法)的信息。
一个完整方法包含的属性有:
方法上使用的注解、方法的修饰符、方法上定义的泛型参数、方法的返回值、方法名称、方法参数(泛型、注解)、方法抛出的异常。

比如下面这个方法:

@MyAnnotation
public <T> boolean add(List<T> list,T...params)throws RuntimeException,Exception{
	if(null==list){
		throw new RuntimeException("list=null");
	}
	
	if(null==params){
		return false;
	}
	//将参数添加到List集合中
	if(null!=params){
		for(T t:params){
			list.add(t);
		}
	}
	return true;
}

注解:@MyAnnotation
修饰符:public
泛型参数:T
返回值:boolean
方法名:add
方法参数(泛型、注解):List<T> list,T...params
抛出的异常:RuntimeException,Exception


package reflect;

import java.lang.annotation.Annotation;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.lang.reflect.WildcardType;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @author zhangquanit
 */
public class MethodTest {

	/**
	 * 一个完整方法包含的属性有: 方法上使用的注解、方法的修饰符、方法上定义的泛型参数、方法的返回值、方法名称、方法参数(泛型、注解)、方法抛出的异常
	 */
	@MyAnnotation
	private <T> boolean add(@MyAnnotation List<T> list, T... params) throws RuntimeException,
			Exception {
		if (null == list) {
			throw new RuntimeException("list=null");
		}

		if (null == params) {
			return false;
		}
		// 将参数添加到List集合中
		if (null != params) {
			for (T t : params) {
				list.add(t);
			}
		}
		return true;
	}

	public static void main(String[] args) throws Exception {
		// 获取Method
		MethodTest obj = new MethodTest();
		Class<? extends MethodTest> clazz = obj.getClass();

		Method method = clazz.getDeclaredMethod("add", List.class,
				Object[].class);
		if (!method.isAccessible()) {
			method.setAccessible(true);
		}
        //获取方法基本信息
		getMethodInfo(method);
		
		// 调用方法
		List<String> arrayList = new ArrayList<String>();
		method.invoke(obj, arrayList, new String[] { "1", "2" });
		System.out.println(arrayList);//[1,2]
		
		//方法定义所在的类
		Class<?> declaringClass = method.getDeclaringClass();
		
		// 如果此方法是 bridge 方法,则返回 true;
		boolean bridge = method.isBridge();
		//如果该方法是public非抽象非静态,且定义在接口中,则返回true
		boolean default1 = method.isDefault(); //false
		//如果此方法为复合方法,则返回 true;
		boolean synthetic = method.isSynthetic();//false
		// 如果将此方法的参数带有可变参数,则返回 true
		boolean varArgs = method.isVarArgs(); //true
		
		
		
	}

	private static void getMethodInfo(Method method) {
		// 1、获取方法上的注解
		boolean annotationPresent = method
				.isAnnotationPresent(MyAnnotation.class);
		if (annotationPresent) {
			MyAnnotation myAnnotation = method
					.getDeclaredAnnotation(MyAnnotation.class);
		}
		// 2、方法的修饰符
		int modifiers = method.getModifiers();
		String modify = Modifier.toString(modifiers);// private
		// 3、方法上定义的泛型参数
		TypeVariable<Method>[] typeParameters = method.getTypeParameters();// [T]
		// 4、方法的返回值
		Class<?> returnType = method.getReturnType();// boolean
		Type genericReturnType = method.getGenericReturnType();// boolean
		// 5、方法名称
		String name = method.getName();
		// 6、方法参数
		int parameterCount = method.getParameterCount();// 参数个数 2
		// 方法参数——泛型
		Class<?>[] parameterTypes = method.getParameterTypes();
		// 打印 [interface java.util.List, class [Ljava.lang.Object;]
		Type[] genericParameterTypes = method.getGenericParameterTypes();
		// 打印 [java.util.List<T>, T[]]
		for (Type type : genericParameterTypes) {
			if (type instanceof ParameterizedType) { // 参数类型
				System.out.println("ParameterizedType类型:" + type);
				ParameterizedType parameterizedType = (ParameterizedType) type;
				Type[] actualTypeArguments = parameterizedType
						.getActualTypeArguments();
				System.out.println("实际参数为:"
						+ Arrays.toString(actualTypeArguments));
				for (Type actualType : actualTypeArguments) {
					if (actualType instanceof WildcardType) {
						WildcardType wildcardType = (WildcardType) actualTypeArguments[0];
						System.out.println("实际参数为WildcardType类型:"
								+ wildcardType.getUpperBounds());
					} else if (actualType instanceof Class) {
						System.out.println("实际参数为Class类型:" + actualType);
					}
				}

			} else if (type instanceof GenericArrayType) { // 泛型数组类型 T[]
				GenericArrayType genericArrayType = (GenericArrayType) type;
				System.out.println("GenericArrayType类型:"
						+ genericArrayType.getGenericComponentType());//T
			} else if (type instanceof TypeVariable) { // 泛型变量
				System.out.println("TypeVariable类型:" + type);
			} else if (type instanceof Class) { //
				System.out.println("Class类型:" + type);
			}
		}
		/*
		 * 方法有2个参数,第一个参数list为ParameterizedType,实际参数为T,
		 * 第二个参数为GenericArrayType泛型数组类型T[],数组元素类型为T
		 */
		
		//方法参数——注解   第一个参数使用了注解
		Annotation[][] parameterAnnotations = method.getParameterAnnotations();
		Annotation myAnnotation=parameterAnnotations[0][0];
		//打印 @reflect.MyAnnotation(intValue=0)
		

		// 7、方法抛出的异常
		Class<?>[] exceptionTypes = method.getExceptionTypes();
		// 打印 [class java.lang.RuntimeException, class java.lang.Exception]
		Type[] genericExceptionTypes = method.getGenericExceptionTypes();
		// 打印 [class java.lang.RuntimeException, class java.lang.Exception]

	}
}


@ExportMethodJava中用于注解方法的一个注解,通常用于框架或库的开发中,以便在运行时动态调用这些方法。它的主要作用是将方法暴露给外部调用者,使得这些方法可以在运行时通过反射机制被调用。 以下是@ExportMethod的一些关键点: 1. **运行时调用**:通过@ExportMethod注解的方法可以在运行时通过反射机制被调用,而不需要在编译时确定调用关系。 2. **灵活性**:这种方法提高了代码的灵活性,使得框架或库可以在不修改原有代码的情况下,动态地调用用户自定义的方法。 3. **参数传递**:通过反射机制,可以传递参数给被注解的方法,并获取方法的返回值。 ### 示例 假设我们有一个简单的服务类,其中包含一个通过@ExportMethod注解的方法: ```java public class MyService { @ExportMethod public String greet(String name) { return "Hello, " + name + "!"; } @ExportMethod public int add(int a, int b) { return a + b; } } ``` 在运行时,我们可以使用反射机制来调用这些方法: ```java import java.lang.reflect.Method; public class Main { public static void main(String[] args) { MyService myService = new MyService(); try { Method greetMethod = myService.getClass().getMethod("greet", String.class); String greeting = (String) greetMethod.invoke(myService, "Alice"); System.out.println(greeting); // 输出: Hello, Alice! Method addMethod = myService.getClass().getMethod("add", int.class, int.class); int sum = (int) addMethod.invoke(myService, 5, 3); System.out.println(sum); // 输出: 8 } catch (Exception e) { e.printStackTrace(); } } } ``` ### 优点 1. **动态性**:可以在运行时动态调用方法,而不需要在编译时确定调用关系。 2. **灵活性**:框架或库可以根据需要动态地调用用户自定义的方法。 3. **扩展性**:用户可以通过自定义方法来实现特定的功能,而不需要修改框架或库的代码。 ### 注意事项 1. **性能开销**:反射机制会带来一定的性能开销,因此在性能敏感的场景下需要谨慎使用。 2. **安全性**:需要确保被调用的方法的安全性,避免潜在的安全漏洞。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值