Java反射的封裝

Java這種以囉嗦著稱的編程語言,反射代碼也很囉嗦。每次看到不少人使用原生的反射接口,我內心都在想,愚蠢的人類啊,爲何不封裝一下再用。java

能用到反射的場景

  • 不能靜態決定,好比根據URL參數的字符串調用相應方法的時候。git

  • 避免樣板代碼的時候,例如能夠用反射代替,繁瑣的JSON對象解析代碼。github

  • 避免顯式依賴的時候,有時候能用來打破項目之間的循環依賴關係。但要慎用,若是之間接口比較複雜,仍是建議單獨使用協議接口的方法。編程

  • 訪問私有成員,作一些黑科技的事情的時候。編程語言

方法調用封裝

封裝前的反射調用方法:code

try {
  Class<?> class = obj.getClass();
  Method method = class.getDeclaredMethod("foo", new Class[] { String.class });
  method.invoke(obj, new Object[] {"hi"});
} catch (Exceptione ex) {
}

非反射直接調用:對象

obj.foo("hi");

封裝後的反射調用:繼承

Reflection.callMethod(obj, "foo", "hi");

字段賦值封裝

封裝前的反射調用方法:接口

try {
  Class<?> class = obj.getClass();
  Field field = class.getDeclaredField("bar");
  field.setAccessible(true);
  Object old = field.get(obj);
  field.set(obj, "hi");
  return old;
} catch (Exceptione ex) {
}

非反射直接字段賦值:字符串

obj.bar = "hi";

封裝後字段賦值:

Reflection.setField(obj, "bar", "hi");

源碼

Talk is cheap, show me the code.

這裏是我簡單的反射封裝代碼,不是很完整,只是解決了目前本身的需求。源碼也就100行,本身看吧。

有Declared和無Declared的區別

在Class類接口中,getDeclaredMethod getDeclaredField和getMethod getField的區別。帶Declared的包含本類的私有和公開成員,不包含繼承的成員。不帶Declare不含繼承的和自身的公開成員,不包含私有成員。若是要訪問全體的成員,包括全部繼承的和私有的,那麼代碼只會更加複雜。幸運的是Reflection類的封裝已經幫你實現了。

相關文章
相關標籤/搜索