java-反射、注解、泛型
2020-06-27 本文已影响0人
isLJli
反射
作用:能够做一般做不到的事情。使用场景:插件式换肤,插件式开发
所有的反射功能都是基于字节码(class),一个类的class在内存宏应该只有一份,而且class其实也是一个对象。
反射创建对象
//反射创建对象
try {
//getDeclaredConstructor从所有构造方法里找,getConstructor从公共构造方法里找
Constructor constructor = TestBean.class.getDeclaredConstructor(String.class);
constructor.setAccessible(true); //设置权限
TestBean testBean1= (TestBean)constructor.newInstance("晴天");
testBean1.getName();
} catch (Exception e) {
e.printStackTrace();
}
反射得到方法
//反射得到方法
try {
Constructor constructor = TestBean.class.getDeclaredConstructor(String.class);
constructor.setAccessible(true); //设置权限
TestBean testBean2= (TestBean)constructor.newInstance("晴天");
Method method2 = TestBean.class.getDeclaredMethod("setName",String.class);//方法的名字
method2.setAccessible(true);
method2.invoke(testBean2,"好心分手");
Method method = TestBean.class.getDeclaredMethod("putName");//方法的名字
method.setAccessible(true);
method.invoke(testBean2);
} catch (Exception e) {
e.printStackTrace();
}
反射得到属性
//反射得到属性
TestBean testBean= new TestBean("小米");
try {
Field field= TestBean.class.getDeclaredField("name");
field.setAccessible(true);
String string=(String)field.get(testBean);
System.out.println("反射拿到属性"+string);
} catch (Exception e) {
e.printStackTrace();
}
当类被隐藏的写法:
//类被隐藏的写法,即不能.class
try {
Class clazz = Class.forName("android.app.ActivityThread");
Field field = clazz.getDeclaredField("sCurrentActivityThread");
field.setAccessible(true);
Object object= field.get(null); //static不用依附对象
System.out.println("得到方法"+object.toString());
} catch (Exception e) {
e.printStackTrace();
}
总结:
1.获取构造函数:
class.getDeclaredConstructor()
2.获取方法:
class.getDeclaredMethod()
3.获取属性
class.getDeclaredField()
注解
注解:只是一个标记,本身没有逻辑代码功能
//上面必须有两个标识
//代表必须放到什么上面 FIELD:属性 TYPE:类 METHOD:方法
@Target(ElementType.FIELD)
//什么时候起作用,RUNTIME:运行时 CLASS:编译打包时 SOURCE:编程时
@Retention(RetentionPolicy.RUNTIME)
public @interface ViewById { //@interface代表注解
int value();
}
public class MainActivity14 extends AppCompatActivity {
@ViewById(R.id.iv_glide)
private Button mBtn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ViewUtils.inject(this);
mBtn.setText("用注解设置值");
}
public class ViewUtils {
public static void inject(Activity activity){
//1.获取所有的属性
Field[] fields = activity.getClass().getDeclaredFields();
//2.过滤关于viewById属性
for (Field field : fields){
ViewById viewById = field.getAnnotation(ViewById.class);
if(viewById != null){
//3.findViewById
View view = activity.findViewById(viewById.value());
//4.反射注入
field.setAccessible(true);
try {
//activity属性所在类,view代表的是属性的值
field.set(activity,view);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
泛型
类泛型
public class ArrayLists<T> {
T value;
public Object[] objects = new Object[10];
public void add(T value){
this.value=value;
objects[0]=value;
}
}
方法泛型
public <T> Dao<T> get(){
return new Dao<T>();
}
泛型上限和下限
public class BaseActivitys extends AppCompatActivity {
//泛型的上限,包括BaseActivitys和它的子类
public void startActivity(Class<? extends BaseActivitys> clazz){
Intent intent = new Intent(this,clazz);
startActivity(intent);
}
//泛型的下限, 包括BaseActivitys和它的父类
public void startActivity1(Class<? super BaseActivitys> clazz){
Intent intent = new Intent(this,clazz);
startActivity(intent);
}
}