注解和反射
一、注解
Annotation 不是程序本身,可以对程序作出解释
可以被其他程序读写
内置注解:
@Override :表示一个方法声明打算重写超类中的另一个方法声明;
@Deprecated:不推荐程序员使用的方法,但可以使用;
@SuppressWarning :镇压警告
元注解:负责解释其他注解
@Target :描述注解适用范围
@Retention:表示需要在什么级别该保存该注释信息,用于描述注解的生命周期
@Documented:说明该注解被包含在javadoc中
@inherited:说明子类可以继承父类中该注解
自定义注解:
package com.annotation;
import java.lang.annotation.*;
public class Test01 {
}
//定义一个注解
@Target(value = {ElementType.METHOD,ElementType.TYPE}) //作用域
@Retention(value = RetentionPolicy.RUNTIME)//runtime>class>source
@Documented
@Inherited
@interface Myannotation{
内容}
二、反射
动态语言:一类在运行时可以改变其结构的语言;反射是Java被视为动态语言的关键Reflection,
反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息,并能直接操作任意对象
内部属性以及方法;
获得反射对象:
Class a = Class.forname(“路径”)
一个类在内存中只有一个class对象
一个类加载后,类的整个结构都会被封装在Class对象中;
三、获取class类
对象通过反射可以得到:类的属性、方法和构造器、某个类实现那些借口
class 本身也是一个类;
class对象只能由系统建立对象;
一个加载的类在JVM中只会有一个class示例;
通过对象获得、通过类名。class获得、通过forname获得、内置函数类型可以自带.TYPE获得
只要元素类型和维度相同就是同一个class;
四、类加载内存分析
类的初始化:类的主动引用 new的时候 通过反射java.lang.reflect :当初始化一个类,若其父类未初始化则先初始化父类
类的被动引用
类加载器:将class文件字节码内容加载到内存中,并且将这些静态数据转换成为方法区的运行时数据接口;
引导类加载器:用来装在核心类
扩展类加载器:负责jre/lib/ext目录下的jar包或D java。ext。dirs制定目录下的jar包装入工作库
系统类加载器:负责java-classpath所指的目录下的类与jar包装入工作,是最常用的加载器;
作用:用来把类加载进内存的
五、通过反射动态创建对象
调用Class对象的newInstance()方法
:类必须有无参构造器
:类的构造器的访问权限需要足够
通过构造器创建对象,传入参数
通过反射获取方法:a.getDeclaredMethod()
通过反射操作属性:a.getDeclaredField(),通过关闭程序安全检测setAccessible(true)才能操作私有属性;
六、获取泛型信息
Java采用范型擦除机制来引入范型,仅仅是给编译器javac使用的,确保数据安全性;
ParameterizedType:表示一种参数化类型,如Collection<String>
GenricArrayType:表示一种元素类型是参数化类型或者类型变量的数组类型;
TypeVariable:是各种类型变量的公共接口;
WildcardType:代表一种通配符类型表达式;
七、反射操作注解
package com.reflect;
import java.lang.annotation.*;
import java.lang.reflect.Field;
public class reflection {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
Class c1 = Class.forName("com.reflect.Student");
//获取注解
Annotation[] annotations = c1.getAnnotations();
for (Annotation annotation : annotations) {
System.out.println(annotation);
}
//获取注解value 的值
Tabledx tabledx = (Tabledx)c1.getAnnotation(Tabledx.class);
String value = tabledx.value();
System.out.println(value);
//获得类指定的注解
Field f = c1.getDeclaredField("id");
Fielddx annotation = f.getAnnotation(Fielddx.class);
System.out.println(annotation.columnName());
System.out.println(annotation.type());
System.out.println(annotation.length());
}
}
@Tabledx("db_student")
class Student {
@Fielddx(columnName = "db_id",type = "int",length = 10)
private int id;
@Fielddx(columnName = "db_age",type = "int",length = 10)
private int age;
@Fielddx(columnName = "db_name",type = "varchar",length = 3)
private String name;
public Student(){}
public Student(int id, int age, String neme){
this.id = id;
this.age = age;
this.name = name;
}
public void setId(int id) {
this.id = id;
}
public void setAge(int age) {
this.age = age;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public int getAge() {
return age;
}
public String getName() {
return name;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", age=" + age +
", name='" + name + '\'' +
'}';
}
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface Tabledx{
String value();
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface Fielddx{
String columnName();
String type();
int length();
}