JAVA反射機制是在運行狀態中,對於任意一個類,都可以知道這個類的全部屬性和方法;對於任意一個對象,都可以調用它的任意方法和屬性;這種動態獲取信息以及動態調用對象方法的功能稱爲java語言的反射機制.java
反射中咱們最常接觸到的類大體有一下幾個:數組
(1) persionClass.getField(方法的名稱);
(2) persionClass.getFields();
(3) persionClass.getDeclaredField(方法的名稱);
(4) persionClass.getDeclaredFields();複製代碼
裏面getField和getFields只能獲取到public修飾的字段,getDeclaredField和getDeclaredFields能夠獲取到全部的字段.其中以s結尾的是獲取全部的字段返回的是一個Field 的數組.(1) persionClass.getMethod(方法的名稱);
(2) persionClass.getMethods();
(3) persionClass.getDeclaredMethod(方法的名稱);
(4) persionClass.getDeclaredMethods();複製代碼
getMethod和getMethods只能獲取到public修飾的方法名稱,getDeclaredMethod和getDeclaredMethods能夠獲取到全部的方法.(1) persionClass.getConstructor(可變參數集合);
(2) persionClass.getConstructors();
(3) persionClass.getDeclaredConstructor(方法的名稱);
(4) persionClass.getDeclaredConstructors();複製代碼
getConstructor和getConstructors只能獲取到public修飾的方法名稱,getDeclaredConstructor和getDeclaredConstructors能夠獲取到全部的方法.建立對象的方法:bash
(1) Constructor.newInstance(可變參數);
eg:Persion p = (Persion)constructor.newInstance("1");複製代碼
(1) field.set(Objkect obj,Object value);
(2) field.setInt(Objkect obj,int value);
...
(n) file.setLong(Objkect obj,long value);複製代碼
獲取屬性對象:ide
(1) field.get(Object);
eg:Person p = (Persion)filed.get(對象);複製代碼
這裏要注意了若是字段的修飾符是Static的話裏面能夠傳入任何值包括null;函數
調用方法:
這裏必須注意的是當操做的對象用private修飾的時候須要用method.setAccessible(true)來設置能夠訪問到.而後調用method.invoke(Object obj,參數),這個Object的對象必須是該類的對象.不是所謂的類對象.ui
Class<? extends TabLayout> tabClass = tabLayout.getClass();
try {
Field mTabStrip = tabClass.getDeclaredField("mTabStrip");
mTabStrip.setAccessible(true);
LinearLayout linearLayout = (LinearLayout) mTabStrip.get(tabLayout);
for (int i = 0; i < linearLayout.getChildCount(); i++) {
View child = linearLayout.getChildAt(i);
child.setPadding(0,0,0,0);
LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) child.getLayoutParams();
// layoutParams.width = 300;
layoutParams.leftMargin = 150;
layoutParams.rightMargin = 150;
child.setLayoutParams(layoutParams);
child.invalidate();
}
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}複製代碼
控制Toast的顯示時間.
Toast內部類TN的設置顯示時間的代碼:this
mParams.hideTimeoutMilliseconds = mDuration ==
Toast.LENGTH_LONG ? LONG_DURATION_TIMEOUT : SHORT_DURATION_TIMEOUT;
...
/**
* schedule handleHide into the right thread
*/
@Override
public void hide() {
if (localLOGV) Log.v(TAG, "HIDE: " + this);
mHandler.obtainMessage(HIDE).sendToTarget();
}複製代碼
這裏系統自帶的Toast只給了咱們兩個時間的選擇SHORT_DURATION_TIMEOUT和LONG_DURATION_TIMEOUT其餘的咱們無法改變.還好系統提供了hide方法不過在外面咱們是訪問不到,這裏咱們也能夠用到反射,大部分的操做都是Toast的內部類TN來完成的.首先獲取到Toast的class對象,Toast內部含有內部類的字段(final TN mTN),這樣咱們能夠獲取到內部類的對象,而後再經過內部類的Class對象來獲取內部類裏面的hide()方法.代碼以下:spa
try{
Class<Toast> toastClass = Toast.class;
Field mTN = toastClass.getDeclaredField("mTN");
//獲取修飾符類型
toastClass.getModifiers();
mTN.setAccessible(true);
Object o = mTN.get(toast);
Class<?> aClass = o.getClass();
Method hide = aClass.getDeclaredMethod("hide");
hide.setAccessible(true);
hide.invoke(o);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}複製代碼
反射對咱們來講仍是挺重要的,咱們不須要多麼的精通只須要在使用的時候不會那麼陌生.對於有java基礎的同窗學起來仍是比較容易的.code
歡迎你們的觀看並提出寶貴的意見cdn