秉承万物皆对象的思想,java类加载到内存空间后,类本身可以被当作对象读取到,类所包含的成员变量,方法,构造方法等都可以作为对象读到内存中,我们拿到这些对象后可以用反射的方式对对象进行各种操作。这也是各个框架的实现原理。
获取Class对象的方式有三种:
1. Class.forName("全类名"):将字节码⽂件加载进内存,返回Class对象
2.类名.class:通过类名。属性class来获取类对象
3.对象名.getClass()方法获取对象所属类对象
结论:同⼀个字节码⽂件(*.class)在⼀次程序运⾏过程中,只会被加载⼀次,不论通过哪⼀种⽅式获取 的Class对象都是同⼀个。
框架使用注解赋值的原理:
1.在定义注解时,使用元注解定义可以使用的范围,定义属性列表和默认值
2.当程序员定义类时,添加对应注解
3.添加注解的类对象被创建时,框架通过反射机制拿到类对象,然后通过isAnnotationPresent(注解类对象)方法判断是否使用注解
4.如果使用了该注解,通过类对象.getAnnotation(注解类对象)获取注解类对象,拿到注解类对象后取得对应注解属性来对类对象进行赋值或者其它操作
注解代码
package com.rxsoft.part15;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.TYPE,ElementType.METHOD,ElementType.FIELD})//注解使用位置
@Retention(RetentionPolicy.RUNTIME)//注解保留到什么时候
public @interface MyAnno {
int age()default 0;
}
package com.rxsoft.part15;
@MyAnno(age = 24)
public class Person {
private int age;
private String name;
public int i;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getI() {
return i;
}
public void setI(int i) {
this.i = i;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void eat(){
System.out.println(name+"吃了一点东西");
};
public Person(int age, String name, int i) {
this.age = age;
this.name = name;
this.i = i;
}
public Person() {
}
}
测试获取注解值代码
package com.rxsoft.part15;
public class TestAnno {
public static void main(String[] args) {
Person person=new Person();
//获取class对象
Class<Person> personClass = Person.class;
//判断是否使用注解
boolean annotationPresent = personClass.isAnnotationPresent(MyAnno.class);
//如果使用注解,拿到注解对象后对person对象的年龄字段进行赋值
if (annotationPresent){
MyAnno annotation = personClass.getAnnotation(MyAnno.class);
person.setAge(annotation.age());
}
//打印输出
System.out.println(person.getAge());
}
}
最终可以看出person对象成功赋值注解属性age=24