-
反射
public class IocBean {
private String name;
public String title = "ioc";
private static Login login = new Login();
public IocBean(){
}
private IocBean(String name){
this.name = name;
}
private void print(){
LogUtils.LogE("name = "+this.name);
}
private void printName(String name1){
LogUtils.LogE("name1 = "+name1);
}
@Override
public String toString() {
return "IocBean{" +
"name='" + name + '\'' +
'}';
}
}
- 1.反射拿到构造函数
Class> clazz = IocBean.class;
try {
//拿到公有的构造
Constructor> constructor1 = clazz.getConstructor();
//拿到私有的构造
Constructor> constructor = clazz.getDeclaredConstructor(String.class);
} catch (NoSuchMethodException e) {
LogUtils.LogE(e.toString());
}
- 2.通过构造去创建对象
//拿到公有的构造
Constructor> constructor1 = clazz.getConstructor();
//拿到私有的构造
Constructor> constructor = clazz.getDeclaredConstructor(String.class);
//有参
IocBean instance = (IocBean) constructor.newInstance("digta");
//无参
IocBean instance1 = (IocBean) constructor1.newInstance();
- 3.反射获取属性修改属性
//拿公有属性
Field field = clazz.getField("title");
String title = (String) field.get(instance);
//修改属性
field.set(instance,"update title");
//拿私有属性
Field field1 = clazz.getDeclaredField("name");
field1.setAccessible(true);
String name = (String) field1.get(instance);
field1.set(instance,"update name");
//获取静态属性
Field field2 = clazz.getDeclaredField("login");
field2.setAccessible(true);
Login login = (Login) field2.get(null);
- 4.反射执行私有方法
//反射执行方法
Method method = clazz.getDeclaredMethod("print");
method.setAccessible(true);
method.invoke(instance);
Method method1 = clazz.getDeclaredMethod("printName",String.class);
method1.setAccessible(true);
method1.invoke(instance,"methodName");
-
注解
- 1.RetentionPolicy.SOURCE:注解只保留在源文件,当Java文件编译成class文件的时候,注解被遗弃;
- 2.RetentionPolicy.CLASS:注解被保留到class文件,但jvm加载class文件时候被遗弃,这是默认的生命周期;
- 3.RetentionPolicy.RUNTIME:注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在;
这3个生命周期分别对应于:Java源文件(.java文件) ---> .class文件 ---> 内存中的字节码。
一般如果需要在运行时去动态获取注解信息,那只能用 RUNTIME 注解;如果要在编译时进行一些预处理操作,比如生成一些辅助代码(如 ButterKnife),就用 CLASS注解;如果只是做一些检查性的操作,比如 @Override 和 @SuppressWarnings,则可选用 SOURCE 注解.
- 1.@Target(ElementType.TYPE) //接口、类、枚举
- 2.@Target(ElementType.FIELD) //字段、枚举的常量
- 3.@Target(ElementType.METHOD) //方法
- 4.@Target(ElementType.PARAMETER) //方法参数
- 5.@Target(ElementType.CONSTRUCTOR) //构造函数
- 6.@Target(ElementType.LOCAL_VARIABLE)//局部变量
- 7.@Target(ElementType.ANNOTATION_TYPE)//注解
- 8.@Target(ElementType.PACKAGE) ///包
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface ViewId {
int value();
}
@ViewId(R.id.tv_ioc)
private TextView mTextView;
@ViewId(R.id.tv_ioc1)
private TextView mTextView1;
@Override
protected void initView(View rootView) {
//test1();
InjectUtils.inject(this,rootView);
mTextView.setText("ioc set hello");
mTextView1.setText("ioc set1 hello1");
}
public static void inject(IocFragment iocFragment, View rootView) {
Class> aClass = iocFragment.getClass();
Field[] fields = aClass.getDeclaredFields();
LogUtils.LogE(fields.length);
for (Field field : fields) {
ViewId annotation = field.getAnnotation(ViewId.class);
if (annotation != null) {
int value = annotation.value();
View view = rootView.findViewById(value);
field.setAccessible(true);
try {
field.set(iocFragment,view);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
-
泛型
-
- ? extends E 规定上边界
//必须是Activity或它的子类
public static void startActivity(Context context, Class extends Activity> clazz){
context.startActivity(new Intent(context,clazz));
}
-
- ? super E 规定下边界
//必须是BaseActivity或者它的父类
public static void startActivity(Context context, Class super BaseActivity> clazz){
context.startActivity(new Intent(context,clazz));
}
List extends Person> list = new ArrayList<>();
//这里会报错,因为Person的子类有很多种,list无法确定是哪一种,这里只能用get方法取值,得到的都是Person
list.add(new Person());
Person person = list.get(0);
List super Person> list = new ArrayList<>();
//这样写不会报错,list将所有元素都当做是Person加入
list.add(new Person());
- 3.方法泛型
//作用于方法上, 省去强转的麻烦
public T getView(View view,int id){
return (T)view.findViewById(id);
}