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);
  }
}
上一篇 下一篇

猜你喜欢

热点阅读