反射 reflect
面向对象的编程思想
类 从很多对象中抽取出来的公有的特征行为,抽象描述用来描述一组对象
现实生活中存在好多对象 很多相同的特征,相同行为
Class 用来描述类本身
Package用来描述类所在属的包
Field用来描述类中属性
Method 用来描述类种方法
Constructor用来所描述类中构造方法
Annotation用来描述类中注解
如何获取Class
如下三种方法:
(1).Class clazz = Class.forName("包名类名")
public class TestReflect {
public static void main(String[] args) {
try {
//获取User的Class对象,参数为需要获取类对象的全类名
Class aClass = Class.forName("sml.reflect.User");
//因为是动态编译,所有我们需要抛出类未找到的异常
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
(2).Class clazz = 类名class;
public class TestReflect {
public static void main(String[] args) {
//通过导包获取类名点class来获取类对象
Class aClass = User.class;
}
}
(3) .Class clazz = 对象.getClass();//Object类中方法
public class TestReflect {
public static void main(String[] args) {
//new一个user对象
User user = new User();
//通过user对象来获取User类对象
Class aClass = user.getClass();
}
}
Class中常用的方法
getModifiles();获取到类中的修饰符(权限 特征)
权限修饰符:public 默认不写 protected private
特征修饰符:final(最终) static(静态)volatile(指令重排)synchronized(锁)
属性:权限修饰符+特征修饰符+类型+属性名称
类中:属性、方法、块、构造方法
(1)int resutlt = getModifiles();获取到类中的修饰符(权限 特征)
0默认不写 1. public 2. private 4. protected 8. static 16. final 512. interface 1024. abstract
(2)String name = getName();获取名字
(3)String simpleName = getSimpleName();//获取简单名
(4)Package p = getPackage();//获取包
(5)Class clazz = getSuperClass();获取超类(父类)
(6)Class[] classes = getlnterface();
(7)Objcet obj=newlnstace());//默认调用无参构造方法创建对象
(8)Filed[] fs=getFields();
(9)Filed[]fs=getDeclareFileds();
Filed类中常用方法
int s = getModifers();
Class clazz = getType();
String name = getName();
操作属性 向里面存储set (对象,值)
操作属性 从里面取值值 = get(对象)
setAccessable(true);
可以修改属性操作
Method类中常用
int mm = m.getModifiers();//获取方法的修饰符(权限+特征)
Class mrt = m.getReturnType();//获取返回值数据类型
String mn = m.getName();//获取方法的名字
Class[] mpts = m.getParameterTypes();//获取方法参数列表的类型
Class[] mets = m.getExceptionTypes();//获取方法抛出异常的类型如何操作方法
调用方法让他执行一次
Object result = invoke(对象,执行方法需要传递的所有参数...)
若方法是私有的方法不允许操作
可以设置setAccessable(true)设置方法使用权准入
Constructor类中的常用方法
con.getModifiers();//获取方法的修饰符(权限+特征)
con.getName();//获取方法的名字
con.getParameterTypes();//获取方法参数列表的类型
con.getExceptionTypes();//获取方法抛出异常的类型
如何操作构造方法
执行一次创建对象
Object = newinstance(执行构造方法时的所有参数)con.setAccessible(true); 设置方法使用权准入
注解
什么是注解
1.用来充当注释的作用(仅仅是一个文字的说明) @Deprecated;2.用来做代码的检测(验证) @Override;*3.可以携带一些信息(内容) 文件.properties .xml 注解
注解与注释
注解,不同于单行注释和多行注释。
对于单行注释和多行注释是给程序员看的。
而注解是可以被编译器或其他程序读取的。程序还可以根据注解的不同,做出相应的处理
常见的Annotation作用
生成文档相关的注解:
@author 标明开发该类模块的作者,多个作者之间使用,分割
@version 标明该类模块的版本
@see 参考转向,也就是相关主题
@since 从哪个版本开始增加的
@param 对方法中某参数的说明,如果没有参数就不能写
@return 对方法返回值的说明,如果方法的返回值类型是void就不能写
@exception 对方法可能抛出的异常进行说明 ,如果方法没有用throws显式抛出的异常就不能写
在编译时进行格式检查(JDK内置的三个基本注解)
@Override: 限定重写父类方法,该注解只能用于方法
@Deprecated: 用于表示所修饰的元素(类,方法等)已过时。通常是因为所修饰的结构危险或存在更好的选择
@SuppressWarnings: 抑制编译器警告
跟踪代码依赖性,实现替代配置文件功能
元注解
@Target:用于描述注解的使用范围
可以通过枚举类型ElementType的10个常量对象来指定
TYPE,METHOD,CONSTRUCTOR,PACKAGE.....
@Retention:用于描述注解的生命周期
可以通过枚举类型RetentionPolicy的3个常量对象来指定
SOURCE(源代码)、CLASS(字节码)、RUNTIME(运行时)
唯有RUNTIME阶段才能被反射读取到
@Documented:表明这个注解应该被 javadoc工具记录。
@Inherited:允许子类继承父类中的注解
自定义注解
一个完整的注解应该包含三个部分:
(1)声明
(2)使用
(3)读取
格式:public @interface 注解名 { 定义体 }
使用@interface自定义注解时,自动继承了java.lang.annotation.Annotation接口
其中的每一个方法实际上是声明了一个配置参数
方法的名称就是参数的名称
返回值类型就是参数的类型(返回值类型只能是基本类型、Class、String、enum)
可以通过default来声明参数的默认值
如果只有一个参数成员,一般参数名为value
我们在使用注解元素时必须要有值,可以定义默认值,空字符串,0或者-1
public @interface TestAnnotation {
//参数默认为空
String value() default "";
}
【元注解】
【修饰符】 @interface 注解名{
【成员列表】
}
public @interface MyAnnotation {
String value() default "hello";
}
- @Target
这个注解的作用主要是用来描述注解的使用范围,说白了就是我们自己定义的注解可以使用在哪个地方。@Target(ElementType.METHOD) public @interface TestAnnotation { //参数默认为空 String value() default ""; }
- @Retention
这个注解的作用就是我们需要告诉编译器我们需要在什么级别保存该注释信息,用于描述注解的生命周期。@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface TestAnnotation { //参数默认为空 String value() default ""; }
- @Document
注解标记的元素,Javadoc工具会将此注解标记元素的注解信息包含在javadoc中。默认,注 解信息不会包含在Javadoc中
- @Inherited
用于控制注解的继承行为。元注解是用于注解其他注解的特殊注解。
@Documented
@Inherited
public @interface Book {
//书名
String name();
//出版日期
String publishedDate();
//作者
String author();
}