1. 程式人生 > >[JAVA]反射機制按順序獲取getDeclaredFields()/getDeclaredMethods()

[JAVA]反射機制按順序獲取getDeclaredFields()/getDeclaredMethods()

>未知的返回順序

     在JDK的API文件裡明確標註了:不能保證getDeclaredFields()/getDeclaredMethods()返回的Fields[] 和 Methods[] 的順序。注意是不能保證返回順序,而不是返回是亂序:它完全可能是亂序,也還可能是按照宣告順序排布

    這是因為,JVM有權在編譯時,自行決定類成員的順序,不一定要按照程式碼中的宣告順序來進行編譯。因此返回的順序其實是class檔案中的成員正向順序,只不過在編譯時這個順序不一定等於宣告時的順序。

    那麼如果我要按順序獲取Fields和Methods該怎麼做呢?

>利用執行時的註解保證返回順序

    我們以按順序獲取Fields為例,先定義一個註解:

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface BeanFieldAnnotation {

	/**
	 * 標註該屬性的順序
	 * @return 該屬性的順序
	 */
	int order();
}
    然後給你所需要按順序排布的Fields打上這個註解,比如:
public final class MyBean {
	@BeanFieldAnnotation(order = 1)
	private String number;
	@BeanFieldAnnotation(order = 2)
	private String dates;
}

    接下來就是最重要的排序方法了。想來大家都用上最新的JDK1.8了,那麼這個方法可以這麼寫:

	private List<Field> getOrderedField(Field[] fields){
		// 用來存放所有的屬性域
		List<Field> fieldList = new ArrayList<>();
		// 過濾帶有註解的Field
		for(Field f:fields){
			if(f.getAnnotation(BeanFieldAnnotation.class)!=null){
				fieldList.add(f);
			}
		}
		// 這個比較排序的語法依賴於java 1.8
		fieldList.sort(Comparator.comparingInt(
				m -> m.getAnnotation(BeanFieldAnnotation.class).order()
				));
		return fieldList;
	}
    這個方法將直接返回按註解BeanFieldAnnotation中order屬性指定順序排布的Field的List(如果某個屬性沒有這個註解則跳過)。