一.注解
java.Annotation
1.1 概述
作用:不是程序本身,对程序作出解释。可以被其他程序读取
格式:以 @注释名 在代码中存在,可以添加参数
1.2 内置注解
@Override
? 说明:仅用于修饰方法,表示一个方法声明打算重写超类中的一个方法
@Deprecated
? 说明:修饰 方法、属性、类,表示不建议使用(存在危险或有更好的选择)
@SuppressWarnings
? 说明:用来抑制编译时的警告信息,不同的是该注解需要传参
- @SuppressWarnings(“all”) //全部
- @SuppressWarnings(“unchecked”) //未检查的
- @SuppressWarnings(value={“unchecked”,“deprecation”})
1.3 元注解 (负责注解其他注解)
@Target
说明:用于描述注解的使用范围
例:@Target( value={ElementType.METHOD , ElementType.TYPE} ) //在方法和类中可用
@Retention
说明:注解级别 SOURCE < CLASS < RUNTIME
例:@Retention( Retentionpolicy.RUNTIME )
@Document(了解)
说明:该注解生成在 javadoc 中
@Inherited(了解)
说明:子类可继承父类中的该注解
1.4 自定义注解
使用 @interface 自定义注解
@Target( value={ElementType.METHOD} )
@Retention( Retentionpolicy.RUNTIME )
@interface MyAnnotation{
String value() default "默认值";
}
二.反射
java.Reflection
2.1 概述
- 实现java动态的关键
- 允许程序在执行期借助 Reflection API 获取任何类的信息(并操作)
正常 引入“包类”名称 -> new实例化对象 -> 取得实例化对象
反射 实例化对象(包含类的完整信息) -> getClass方法 -> 得到“包类名称”
- 优缺点
- 优:实现了动态创建对象和编译,体现出java的灵活性
- 缺:影响性能,不建议大量使用
2.2 Class类与Class实例
导包
java.lang.class 类
java.lang.reflect.Method 类的方法
java.lang.reflect.Field 类的成员变量
java.lang.reflect.Constructor 构造器
获取类的方法
Class c1 = person.getClass();
Class c2 = Class.forName("reflection.Student");
Class<Student> c3 = Student.class;
Class c4 = c1.getSuperclass();
2.3 类的加载与 ClassLoader
2.3.1 Java运行原理
加载:将class字节码加入内存,将静态数据换成方法区的运行时数据结构,生成类
链接:java代码合并到 JVM 运行状态中
初始化:执行类构造器() 方法
2.3.2 什么时候会发生类初始化
- 主动引用
- 当虚拟机启发,会初始化main方法所在类
- new 一个类的对象
- 初始化一个类,会先初始化其父类
- 调用静态成员变量和静态方法
- 对类进行反射调用
- 被动引用
- 通过子类引用父类静态变量,不会初始化子类
- 数组定义类引用,不会触发此类初始化 // 类名[] arr= new 类名[10];
- 引用常量,不会触发此类初始化
2.3.3 类加载器
getClassLoader() 获取类加载器
2.4 获取运行时类的完整结构
方法 | 说明 |
---|
Class.getName() | 获得包名 | Class.getFields() | 获取所有public属性 | Class.getDeclaredFields() | 获取所有属性 | Class.getMethods() | 获得类方法及其继承的方法 | Class.getDeclaredMethods() | 获得本类中所有方法 | Class.getMethod(name,…p) | 获得指定方法(方法名,参数类型) | Class.getConstructors() | 获得构造器 |
* 注:获得多个属性或方法的返回值是数组
2.5 调用运行时类的指定结构
2.5.1 动态创建对象newInstance()
User user = new User();
Class aClass = user.getClass();
User obj1 = (User)aClass.newInstance();
System.out.println(obj1.toString());
Constructor constr = aClass.getDeclaredConstructor(String.class, int.class);
User obj2 = (User)constr.newInstance("张三", 003);
System.out.println(obj2.toString());
**2.5.2 调用方法 **invoke(对象,参数)
Method setName = aClass.getDeclaredMethod("setName", String.class);
setName.invoke(obj1,"李四");
System.out.println(obj1.getName());
2.5.3 操作属性
Field name = aClass.getDeclaredField("name");
name.set(obj1,"王五");
System.out.println(obj1.getName());
2.5.4 扩展
1.获取泛型:编译完成后,泛型有关的类型全部擦除 > 通过反射操作类型
2.获取注解: 利用注解和反射完成类和表结构的映射
|