這getAllFields
實施是非常低效率,創建多個ArrayList
實例和數組,重複地在它們之間來回複製整個數據。值得慶幸的是,階級層級很少深刻,這成爲一個瓶頸。
不過,你可以用一個直接的循環,這是更簡單,更高效的實現這一點:
public static Field[] getAllFields(Class<?> klass) {
List<Field> fields = new ArrayList<>();
for(; klass!=null; klass=klass.getSuperclass())
Collections.addAll(fields, klass.getDeclaredFields());
return fields.toArray(new Field[0]);
}
沒有從這裏使用遞歸半點好處。
有了一個循環,你可以輕鬆地創建一個Function
如果你真的想:
public void init(){
Function<Class<?>,Field[]> f = klass -> {
List<Field> fields = new ArrayList<>();
for(; klass!=null; klass=klass.getSuperclass())
Collections.addAll(fields, klass.getDeclaredFields());
return fields.toArray(new Field[0]);
};
Field[] someFields = f.apply(SomeClass.class);
}
雖然,當然,竟然沒有把環路成Function
在所有的理由。由於希望使用低效的遞歸實現,因此您只想在此處有一個函數,但lambda表達式根本不支持訪問它們。他們只能訪問字段,實現功能接口的實例已存儲到該實例中,如果存儲在您不想要的字段中,那麼它們就是。用本地lambda表達式,遞歸是不可能的。
有了直接的循環,你可以只寫
public void init(){
List<Field> fields = new ArrayList<>();
for(Class<?> klass=SomeClass.class; klass!=null; klass=klass.getSuperclass())
Collections.addAll(fields, klass.getDeclaredFields());
Field[] someFields = fields.toArray(new Field[0]);
}
不過,實際上,很少有針對fields
內容複製到陣列中的真正的原因,你可以只用List<Field>
工作,而不是。這就是說,將循環封裝到描述其目的的命名方法中,如getAllFields
,實際上是一件好事。如果您不想公開它,請將其聲明爲private
而不是public
。
目標是什麼?混淆你的代碼?有很多情況下使用lambdas是有用的,但這實際上不是其中之一。 –
請顯示您嘗試過的內容,並解釋您遇到的問題。 – shmosel
我不同意,我認爲一旦你的整個代碼邏輯被封裝在1個方法中,它就更容易維護 – Benma