- 元注解:负责注解其他的注解,Java定义了4个标准的meta-annotation类型
@Target:用于描述注解的适用范围
@Retention:表示需要再什么级别保存该注解信息,用于描述注解的生命周期(source<class<runtime)
@Document:该注解江北包含在javadoc中
@Inherited:说明子类可以继承父类中的注解 - 自定义注解
@Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface MyAnnotation { //类型 参数名() 默认值 String value() default ""; }
- 动态语言:就是在运行代码时可以根据某些条件改变自身结构
静态语言:运行是结构不可变,如java,c++
但java有一定的动态性,可以利用反射机制获得类似动态语言的特性,使编程更加灵活 - 获取Class对象的三种方式
//一个Person类 public class Person { private String name; private int age; public Person() { } public Person(String name, int age) { this.name = name; this.age = age; } 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; } } //通过三种方式获得Class对象 import domain.Person; public class ReflectDemo { public static void main(String[] args) throws ClassNotFoundException { //1.Class.forName("全类名") Class cls0 = Class.forName("domain.Person"); System.out.println(cls0); //2.类名.class Class cls1 = Person.class; System.out.println(cls1); //3.对象.getClass() Person p = new Person(); Class cls2 = p.getClass(); System.out.println(cls2); } }
- class,interface,[],enum,annotation,primitive type,void都有Class对象
- 类加载分为三个部分:加载,连接,初始化
加载:将.class文件的二进制字节流读入内存,并在堆内存中为之创建Class对象,作为.class进入内存后的数据的访问入口。
为何取消方法区?
方法区存储类的元数据信息,我们不清楚一个程序到底有多少类需要被加载,且方法区位于JVM内存,我们不清楚需要给方法区分配多大内存,太小容易PermGen OOM,太大,在触发Full GC时又极其影响性能,同时还存在一些内存泄露的问题
连接:分为三个阶段,验证,准备,解析
验证:为了保证加载进来的字节流符合JVM的规范,不会对JVM有安全性问题。
准备:准备阶段的主要任务是为类的类变量开辟空间并赋默认值。
解析:该阶段的主要职责为将Class在常量池中的符号引用转变为直接引用,此处针对的是静态方法及属性和私有方法与属性。
初始化:该阶段主要是为类的类变量初始化值的,在声明类变量时,直接给变量赋值或者在静态初始化块为类变量赋值 - 反射的作用:动态创建对象,动态操作属性,动态调用方法
- Class类的常用方法:
getFields()—— 获得类的public类型的属性;getDeclaredFields()—— 获得类的所有属性;getField(String name)—— 获得类的指定属性; getMethods()—— 获得类的public类型的方法;getMethod (String name,Class [] args)—— 获得类的指定方法; getConstrutors()—— 获得类的public类型的构造方法;getConstrutor(Class[] args)—— 获得类的特定构造方法; newInstance()—— 通过类的无参构造方法创建对象; getName()—— 获得类的完整名字; getPackage()—— 获取此类所属的包; getSuperclass()—— 获得此类的父类对应的Class对象