美文网首页
java 基础回顾 - 反射

java 基础回顾 - 反射

作者: __Y_Q | 来源:发表于2020-09-23 13:54 被阅读0次

反射就是把java类中的各种成分映射成一个个的 Java 对象
反射的主要目的是为了获取受保护的或者是隐藏的 类/字段/方法, 然后调用.
在反射中所有的功能都是基于字节码 ( class ). class 在内存中应该只有一份, 而且 class 其实也是一个对象 Class.

  • 反射方式一, 构造函数的调用
    已知 TestBean 的构造函数为私有, 外界无法通过 new TestBean 来创建对象
public class TestBean {
    private String name = "zhangsan";
    private TestBean(String name) {
        this.name = name;
    }
    private void sysName() {
        Log.e("--TestBean--", name);
    }
}

调用方式

Constructor<TestBean> constructor = TestBean.class.getDeclaredConstructor(String.class);
//如果调用了无参构造, newInstance()不需要传递参数
TestBean testBean = constructor.newInstance("王二");

getConstructors() 所有公有的构造方法
getDeclaredConstructors() 获取所有的构造方法(包括私有、受保护、默认、公有)
getConstructor(Class... parameterTypes) 获取单个的公有的构造方法
getDeclaredConstructor(Class... parameterTypes) 获取某个构造方法可以是私有的, 或受保护, 默认, 公有

 

  • 反射方式二, 私有方法的调用
    在方式一的基础上想要调用调用 TestBean.sysName() 方法
Method method = TestBean.class.getDeclaredMethod("sysName");
//忽略访问修饰符
method.setAccessible(true);
//参数 1, 就是要调用的对象, 可以理解为, 调用发生在那个对象内, 
//参数 2..... 可为多个参数, 如果要调用的方法有参数, 在参数 2 处可输入多个实参.
method.invoke(testBean);

getMethods() 获取所有公有方法 (包含了父类的方法也包含 Object 类)
getDeclaredMethods() 获取所有的成员方法, 包括私有的(不包括继承的)
getMethod(String name,Class<?>... parameterTypes) 获取单个的.

 

  • 反射方式三, 获取私有字段
Field field = TestBean.class.getDeclaredField("name");
field.setAccessible(true);
//参数 1, 要获取字段所在的对象
String name = (String) field.get(testBean);

getFields() 获取所有共有字段
getDeclaredFields() 获取所有字段, 包括: 私有, 受保护, 默认, 公有
getField(String fieldName) 获取某个公有的字段
getDeclaredField(String fieldName) 获取某个字段(可以是私有的)

这里获取到的 name 值, 就为 TestBean 中的 name 值.

  • 反射方式四, Class.forName
    有时候, 我们是无法拿到 xxx.class 的, 比如 Android 中的 ActivityThread. 这时候就需要 Class.forName 来帮我们达到这一目的了. 例如我们需要获取到 ActivityThread 中的私有静态变量 sCurrentActivityThread
Class clazz = Class.forName("android.app.ActivityThread");
Field currentActivityThread = clazz.getDeclaredField("sCurrentActivityThread");
currentActivityThread.setAccessible(true);
// 如果是静态的, 可以直接传入 Null
Object o = currentActivityThread.get(null);

使用注解和反射实现一个简单的 findViewById

  • 先声明一个注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface FindViewById {
    int value();
    String name() default "zhangsan";
}
  • 接着在工具类中, 创建一个方法来反射获取传入的 Activity 中所有的字段, 接着遍历所有字段, 判断字段是否包含我们声明的注解. 如果包含, 表示是我们需要的, 然后开始注入 findViewById
public class ViewUtils {
    public static void inject(Activity activity){
        //通过反射拿到所有的字段
        Field[] fields = activity.getClass().getDeclaredFields();
        for (Field field : fields) {
            //只要加了我们这个注解的属性
            FindViewById findViewById = field.getAnnotation(FindViewById.class);
            if(findViewById != null){
                View view = activity.findViewById(findViewById.value());
                try {
                    //开始注入
                    field.setAccessible(true);
                    //第一个参数表示 属性所在类, 第二个表示属性的值
                    field.set(activity,view);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
  • MainActivity 中使用
public class MainActivity extends AppCompatActivity {
    @FindViewById(R.id.tv)
    private TextView tv;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ViewUtils.inject(this);
        tv.setText("2222");
    }
}

相关文章

  • java 基础回顾 - 反射

    反射就是把java类中的各种成分映射成一个个的 Java 对象反射的主要目的是为了获取受保护的或者是隐藏的 类/字...

  • Java基础:反射

    反射注解动态代理相关阅读 Java基础:类加载器 Java基础:反射 Java基础:注解 Java基础:动态代理 ...

  • Java基础再回顾-Java反射

    静态加载和动态加载 为了更好地了解Java反射,我们先来理解一下Java的静态加载和动态加载。 静态加载 静态加载...

  • Java基础之反射

    Java基础之—反射(非常重要)Java中反射机制详解Java进阶之reflection(反射机制)——反射概念与...

  • Java基础之反射

    Java基础之反射 反射基本介绍 反射的使用通过反射调用属性和方法通过反射获取配置文件 反射基本介绍 Java反射...

  • Java基础:注解

    系列阅读 Java基础:类加载器 Java基础:反射 Java基础:注解 Java基础:动态代理 1. 概述 注解...

  • Java基础特性回顾——反射(reflect)

    原文:格子衫幽默 概述 概念性的东西不用多说,大家可以百度,我这边就copy下: JAVA反射机制是在运行状态中,...

  • Java高级知识

    反射 sczyh30 深入解析Java反射(1) - 基础深入解析Java反射(2) - invoke方法深入探究...

  • Java基础:动态代理

    系列阅读 Java基础:类加载器 Java基础:反射 Java基础:注解 Java基础:动态代理 概述 在运行时,...

  • java 反射进阶

    1.java反射基础 2.java反射进阶 上一节介绍了反射基础,本节介绍更深入的反射概念。 1.获取不到Clas...

网友评论

      本文标题:java 基础回顾 - 反射

      本文链接:https://www.haomeiwen.com/subject/wuonyktx.html