Java: リフレクション、アノテーション、ジェネリックス

1. 反省

役割:普通はできないことをすること

使用シナリオ: プラグインスキニング、プラグイン開発

すべてのリフレクション関数は、3 つの部分で構成されるクラス バイトコードに基づいています。

  • ファイル: プロパティ
  • コンストラクター: コンストラクター
  • メソッド:メソッド

public class TestBean {
    private String name="xiaoming";//属性

    public TestBean(String name,int age){// 构造函数
        this.name = name;
    }

    public void sysName(){//方法
        Log.e("TAG",name);
    }
    
    private void say(String desc){
        Log.e("TAG",name + " : "+desc);
    }
}

コンストラクター呼び出し

   try {
        Constructor<TestBean> constructor = TestBean.class.getDeclaredConstructor(String.class, int.class);
        constructor.setAccessible(true);
        TestBean testBean = constructor.newInstance("名称", 18);
        testBean.sysName();
    } catch (Exception e) {
        e.printStackTrace();
    }

TestBean testBean = TestBean.class.newInstance(パラメータ タイプ);

getDeclaredConstructor はすべてのコンストラクターから検索します
getConstructor はパブリック コンストラクターから検索します

constructor.setAccessible(true);//権限を設定する

メソッド呼び出し

Method method = TestBean.class.getDeclaredMethod("say",String.class);
method.setAccessible(true);
method.invoke(constructor,"描述信息");

属性呼び出し

Field field = TestBean.class.getDeclaredField("name");
field.setAccessible(true);
String name = (String) field.get(testBean);

2. 注意事項

アノテーションは単なる識別子であり、特定の機能はありません

@Target(ElementType.FIELD)  
@Retention(RetentionPolicy.RUNTIME)
public @interface ViewById {// @interface 代表注解
    int value();
}

@Target: どこに配置するか

  • ElementType.METHOD: メソッドに作用します。
  • ElementType.Type: クラスに作用します。
  • ElementType.Field: 属性に作用する

@保持:

  • RetentionPolicy.RUNTIME: ランタイム (xUtils など)
  • RetentionPolicy.CLASS: コンパイル時間 (パッケージ時間)、例: ButterKnife
  • RetentionPolicy.SOURCE: プログラミング中

注釈とリフレクションを組み合わせて findViewById インジェクションを解決する

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 (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

3. ジェネリック医薬品

クラスジェネリック: どこにでも出現し、同じ型を表します

メソッド ジェネリックス: メソッドに作用する

上限: クラス名 <? extends class> オブジェクト名 クラスとそのサブクラス

下限: クラス名 <? super class> オブジェクト名 class とその親クラス

おすすめ

転載: blog.csdn.net/weixin_42277946/article/details/131034839