注解和反射 – 简笔
1.内置注解
- @Override 重写超类的方法
- @Deprecated 不推荐使用,但是可以使用
- @SuppressWarning 镇压警告 可以使用的参数有 all
2.元注解
元注解是就是解释其他注解的注解 meta-annotation
- @Target 描述注解的使用范围
TYPE,
/** Field declaration (includes enum constants) */
FIELD,
/** Method declaration */
METHOD,
/** Formal parameter declaration */
PARAMETER,
/** Constructor declaration */
CONSTRUCTOR,
/** Local variable declaration */
LOCAL_VARIABLE,
/** Annotation type declaration */
ANNOTATION_TYPE,
/** Package declaration */
PACKAGE,
/**
* Type parameter declaration
*
* @since 1.8
*/
TYPE_PARAMETER,
/**
* Use of a type
*
* @since 1.8
*/
TYPE_USE
- @Retention 描述注解的生命周期 Runtime>Class>Sources
- @Document 该注解将被包含到javadoc中
- @Inherited 说明子类可以继承父类中的该注解
3.自定义注解
// 注解可以显示赋值
// 如果没默认值就一定要现实赋值
// 默认值-1表示不存在
// 如果只有一个参数,并且名为value,那么赋值的时候可以省略value
// 格式 自动继承java.lang.annotation.Annotation接口
public @interface XXX {
// 定义内容
ElementType[] value(); // 参数 类型只能是 基本类型,Class,Sting,enum 以括号结尾() 后面可以跟default 来给一个默认值
}
4.反射机制
java不是动态语言,可以称为"准动态语言",具有一定的动态性
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
4.1 创建class类的方式
- 对象.getClass()
- 类.class
- forName(类的全路径)
- 内置对象包装类.TYPE
4.2 哪些类型有Class对象
- class
- interface
- 数组
- enum
- annotation
- primitive type
- void
ps:对于数组来说,只有维度和长度一样,Class就一样
4.4 类加载器
类加载的作用
将class文件字节码内容加载到内存中,并将这些静态数据转换成方法区的运行时数据结构,然后再堆中生成一个代表这个类的Class对象,作为方法区中类数据的访问入口.
类缓存
标准的javaSE类加载器可以按要求查找类,但一旦某个类加载到类加载器中,它将加载(缓存)一段时间.不过jvm(gc)垃圾回收机制可以回收这些Class对象.
类加载器的类型
- 引导类加载器 是C++写的,无法直接获取
- 拓展类加载器
- 系统类加载器
双亲委派机制
如果引导类加载器和拓展类加载器中含有自己写的同名的class,那么会优先使用其中的类,而不是自己写的类(保证安全)
4.5 获取运行时类的结构
- 获取类的属性
getFields() 获取所有的public属性
getDeclaredFields() 获取所有的属性
- 获得类的方法
getMethods() 获取本类以及父类的所有方法
getDeclaredMethods() 获取本类的所有方法
4.6 通过反射动态创建对象
创建类的对象
调用Class对象的newInstance()方法
- 类必须有一个无参构造函数
- 类的构造器访问权限要足够
newInstance() // 实际是调用无参构造器
- 可以通过获取构造器来创建对象
4.7 提升效率
如果一个反射语句需要反复调用,那么调用setAccessible(true)方法可以提升其执行效率
本质上,是关闭了安全检测
4.8 反射操作泛型
测试demo
package reflection;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
public class Test02 {
public static List<Integer> fun(Map<Integer, String> map){
return null;
}
public static void main(String[] args) throws NoSuchMethodException {
Method method = Test02.class.getDeclaredMethod("fun", Map.class);
// 获取泛型方法的输入参数
Type[] types = method.getGenericParameterTypes();
for (Type type : types) {
System.out.println(type);
if (type instanceof ParameterizedType){
Type[] actualTypeArguments = ((ParameterizedType) type).getActualTypeArguments();
for (Type actualTypeArgument : actualTypeArguments) {
System.out.println(actualTypeArgument);
}
}
}
// 获取泛型方法的返回参数
Type type = method.getGenericReturnType();
System.out.println(type);
if (type instanceof ParameterizedType){
Type[] actualTypeArguments = ((ParameterizedType) type).getActualTypeArguments();
for (Type actualTypeArgument : actualTypeArguments) {
System.out.println(actualTypeArgument);
}
}
}
}
结果集合
java.util.Map<java.lang.Integer, java.lang.String>
class java.lang.Integer
class java.lang.String
java.util.List<java.lang.Integer>
class java.lang.Integer
4.9 获取注解
orm
Object relationship Mapping -> 对象关系映射
- 类和表结构对应
- 属性和字段对应
- 对象和记录对应
demo
package reflection;
import java.lang.annotation.*;
public class Test03 {
public static void main(String[] args) throws NoSuchFieldException {
Class clzz = People.class;
// 通过反射获得注解
Annotation[] annotations = clzz.getAnnotations();
for (Annotation annotation : annotations) {
System.out.println(annotation);
}
// 获取注解的value
Table table = (Table)clzz.getAnnotation(Table.class);
System.out.println(table.value());
// 获得类指定注解
java.lang.reflect.Field id = clzz.getDeclaredField("id");
Field field = id.getAnnotation(Field.class);
System.out.println(field.name());
System.out.println(field.type());
System.out.println(field.len());
}
}
@Table("people")
class People{
@Field(name = "id", type = "int", len = 10)
private int id;
@Field(name = "name", type = "varchar", len = 20)
private String name;
@Field(name = "age", type = "int", len = 10)
private int age;
public People() {
}
public People(int id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "People{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
// 类名注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface Table{
String value();
}
// 属性注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface Field{
String name();
String type();
int len();
}
结果
@reflection.Table(value=people)
people
id
int
10