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