为何添加println后Java反射方法的控制台输出顺序反转?
问题描述
我只修改了一行代码(取消注释System.out.println();),就发现控制台输出顺序变了:原本是methodA在前、methodB在后,取消注释后变成methodB在前、methodA在后。我知道println是换行,但为什么会导致输出顺序反转?
相关代码如下:
UserClass类
public class UserClass { @UserAnnot (value="A") public void methodA() { System.out.println("methodA() execution"); } @UserAnnot (value="B", number=10) public void methodB() { System.out.println("methodB() execution"); } }
UserAnnot注解类
import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @Retention (RetentionPolicy.RUNTIME) public @interface UserAnnot { String value(); int number() default 5; }
AnnotationEx主类
import java.lang.reflect.Method; public class AnnotationEx { public static void main(String[] args) throws Exception { Method method[] = UserClass.class.getDeclaredMethods(); for(int i=0; i<method.length; i++) { String methodName = method[i].getName(); UserAnnot annot = method[i].getAnnotation(UserAnnot.class); System.out.print(methodName + " annotation "); System.out.print("value : "+ annot.value() + " "); System.out.print("number : "+annot.number()+ " "); method[i].invoke(new UserClass(), null); //System.out.println(); } } }
问题解答
这不是System.out.println()导致的顺序反转,核心原因是Java反射获取类方法的顺序没有固定保证。
根据Java语言规范,Class.getDeclaredMethods()返回的方法数组顺序是不确定的——既不按代码中方法定义的顺序,也不按名称排序,不同JVM实现、不同运行环境甚至同一段代码多次运行,返回的方法顺序都可能不一样。
你看到的“取消注释println就反转顺序”只是巧合:两次运行时JVM返回的Method数组顺序本身就不同了,println只是输出换行,不会改变反射获取方法的逻辑。
如果需要固定的遍历顺序,比如按方法名称排序,可以手动对Method数组进行排序:
import java.lang.reflect.Method; import java.util.Arrays; import java.util.Comparator; public class AnnotationEx { public static void main(String[] args) throws Exception { Method method[] = UserClass.class.getDeclaredMethods(); // 按方法名称升序排序 Arrays.sort(method, Comparator.comparing(Method::getName)); for(int i=0; i<method.length; i++) { String methodName = method[i].getName(); UserAnnot annot = method[i].getAnnotation(UserAnnot.class); System.out.print(methodName + " annotation "); System.out.print("value : "+ annot.value() + " "); System.out.print("number : "+annot.number()+ " "); method[i].invoke(new UserClass(), null); System.out.println(); } } }
内容的提问来源于stack exchange,提问作者user25500985
相关产品推荐
相关产品推荐

