反射
一、什么是反射:
(1)Java反射机制的核心是在程序运行时动态加载类并获取类的详细信息,从而操作类或对象的属性和方法。本质是JVM得到class对象之后,再通过class对象进行反编译,从而获取对象的各种信息。
(2)Java属于先编译再运行的语言,程序中对象的类型在编译期就确定下来了,而当程序在运行时可能需要动态加载某些类,这些类因为之前用不到,所以没有被加载到JVM。通过反射,可以在运行时动态地创建对象并调用其属性,不需要提前在编译期知道运行的对象是谁
解释说明:
反射
一般/正常情况下,我们使用某个类时必定知道它是什么类,是用来做什么的,并且能够获得此类的引用。于是我们直接 对这个类进行实例化,之后使用这个类对象进行操作。比如String类,我们知道这个是处理字符串的类,我们可以 new String()获得它的实例,然后调用它的方法属性之类的。
反射则是一开始并不知道我要初始化的类对象是什么,自然也无法使用
new
关键字来创建对象了。这时候,我们 使用 JDK
提供的反射
API
进行反射调用。
反射就是在运行状态中
,
对于任意一个类
,
都能够知道这个类的所有属性和
方法
;
对于任意一个对象
,
都能够调用它的任意方法和属性
;
并且能改变它的属性。
是
Java
被视为动态语言的关键。
Java
反射机制主要提供了以下功能:
在运行时构造任意一个类的对象
在运行时获取或者修改任意一个类所具有的成员变量和方法
在运行时调用任意一个对象的方法(属性)
Class
反射始于
Class
,
Class
是一个类,封装了当前对象所对应的类的信息。
一个类中有属性,方法,构造器等,比如说
有一个
Person
类,一个
Order
类,一个
Book
类,这些都是不同的类,现在需要一个类,用来描述类,这就是 Class,它应该有类名,属性,方法,构造器等。
Class
是用来描述类的类。
Class
类是一个对象照镜子的结果,对象可以看到自己有哪些属性,方法,构造器,实现了哪些接口等等。对于每 个类而言,JRE
都为其保留一个不变的
Class
类型的对象。一个
Class
对象包含了特定某个类的有关信息。 对象只 能由系统建立对象,一个类(而不是一个对象)在 JVM
中只会有一个
Class
实例。
二、反射的原理:
Class对象的由来是将.class文件读入内存,并为之创建一个Class对象。
三:反射始于Class, Class对象的获取
获得
Class
对象
获取
Class
对象的三种方式
1.
通过类名获取
类名
.class
2.
通过对象获取
对象名
.getClass()
3.
通过全类名获取
Class.forName(
全类名
)
classLoader.loadClass(
全类名
)
1.使用 Class 类的 forName 静态方法
2.直接获取某一个对象的 class
3.调用某个对象的 getClass() 方法
获取类的成员变量(字段)信息、同理方法
Method
/构造器
tConstructor
四:反射的用法
用法一:通过反射,调用构造方法
用法二:
MainActivity
InjectView
InjectUtils
重点内容
filed.set(activity, view); // 这里为啥是传activity对象,是一个对象类型,不是null,不是Oject 类型?
MyClass
与声明一个
"
Class
"
不同的是,注解的声明使用
@interface
关键字。一个注解的声明如下:
编译后的R.class文件以及输出打印,如下:
注解
一:注解的概念
Java
注解(
Annotation
)又称
Java
标注,是
JDK5.0
引入的一种注释机制。
注解是元数据的一种形式,提供有关于程序但不属于程序本身的数据。注解对它们注解的代码的操作没有直接影响。
二:注解的声明:使用 @interface 关键字
注解的声明:使用 @interface 关键字
@Target
ElementType.ANNOTATION_TYPE
应用于注解类型。
ElementType.CONSTRUCTOR
应用于构造函数。
ElementType.FIELD
应用于字段或属性。
ElementType.LOCAL_VARIABLE
应用于局部变量。
ElementType.METHOD
应用于方法级注解。
ElementType.PACKAGE
应用于包声明。
ElementType.PARAMETER
应用于方法的参数。
ElementType.TYPE
应用于类的任何元素。
@Retention
RetentionPolicy.SOURCE
-
标记的注解仅保留在源级别中,并被编译器忽略。
RetentionPolicy.CLASS
-
标记的注解在编译时由编译器保留,但
Java
虚拟机
(JVM)
会忽略。
RetentionPolicy.RUNTIME
-
标记的注解由
JVM
保留,因此运行时环境可以使用它。
@Retention
三个值中
SOURCE < CLASS < RUNTIME
,即
CLASS
包含了
SOURCE
,
RUNTIME
包含
SOURCE
、 CLASS。
注意:在使用注解时,如果定义的注解中的类型元素无默认值,则必须进行传值。
注:如果只存在value元素需要传值的情况,则可以省略:元素名=,即省略 value=
如果不是value, 省略“value= ”就是报错,如下,此时的解决方案是,name=james