元注解
使用在注解上的注解就是元注解。
@Target:作用:告诉该注解使用的范围,默认是所有位置都可使用
TYPE可以使用在类上
FIELD可以使用在属性上
METHOD使用在方法上
PARAMETER使用在方法参数上
CONSTRUCTOR使用在构造方法上
@Retention:作用:该注解什么时候有效,默认:SOURCE
SOURCE:源码时有效
CLASS:字节码时有效
RUNTIME:运行时有效。【采用的最多】
@Documented:作用:在代码生成api文档时是否存在该注解
自定义注解的高级
我们发现我们之前使用@GetMapping注解时可以有属性值,我们自定义注解如何赋值?
格式:
@interface 注解名{
数据类型 属性名();
}
数据类型可以是哪些类型?
数据类型可以是基本数据类型,字符串类型,枚举类型,注解类型,数组类型
@Target(ElementType.TYPE)
public @interface My {
int age() ; //基本数据类型
String name(); //字符串类型
MyEnum address(); //枚举类型
My1 my1(); //注解类型
int[] ages(); //数组类型
String[] names();
MyEnum[] addresss();
My[] mys();
}
如果属性定义好之后,使用该注解需要指定属性的值。
//如果属性为数组类型,给数组类型赋值时如果只有一个值那么可以省略{}
//如果该注解中只使用value属性,那么value属性名可以省略。
@My(age = 15,name="成俊杰",address = MyEnum.BEIJING,my1 = @My1,ages = {15,20})
@My1(value="np",name="cjj")
public class My3 {
}
反射
反射它是框架设计的灵魂。
框架: 它就是一个半成品,客户可以引入该框架,在框架的基础上填写自己的业务代码。提高开发效率。 比如: springmvc mybatis框架 。
反射;它就是把类中成员封装到其他类对象的形式。再通过该对象可以获取成员的信息。
获取Class类的反射类的方式
获取Class反射类有三种方式:
第一种:Class.forName("类的全路径")
第二种:类.class
第三种:对象名.getClass
public class Test05 {
public static void main(String[] args) throws ClassNotFoundException {
//第一种方式
Class<?> a = Class.forName("demo05.Student");
//第二种
Class<Student> b = Student.class;
//第三种
Student student = new Student();
Student student1 = new Student();
Class<? extends Student> c = student.getClass();
Class<? extends Student> c1 = student1.getClass();
//比较对象的引用地址,结果全部为true
System.out.println(a==b);
System.out.println(a==c);
System.out.println(b==c);
System.out.println(c==c1);
}
}
class Student{
String name;
int age;
}
在Java中,每个类都有一个唯一的Class对象,表示该类的类型。在第三种方式中,我们通过实例化一个对象来获取该对象的Class对象,因为每个实例化的对象都属于该类的类型,所以这两个对象的Class对象是相同的,因此c和c1的引用地址也相同。
通过反射类获得对应的类对象
格式:反射对象.newInstance()
通过反射类获取属性类对象
获取本类中指定的属性对象:
反射类.getDeclaredField("属性名")
获取本类中所有的属性对象:
反射类.getDeclaredFields()
获取本类以及父类中所有public属性对象
反射类.getFields()
获取本类以及父类中指定的public对象
反射类.getField("属性名")
public class Test {
public static void main(String[] args) throws Exception {
Class<Student> stu = Student.class;
//获取本类中指定的属性对象
Field name = stu.getDeclaredField("name");
System.out.println(name);
//获取本类中所有的属性对象
Field[] names = stu.getDeclaredFields();
System.out.println(Arrays.asList(names));
//获取本类以及父类中public属性对象
Field[] fields = stu.getFields();
System.out.println(Arrays.asList(fields));
//获取本类以及父类中指定的public对象
Field name1 = stu.getField("age");
System.out.println(name1);
}
}
class Teacher{
private String name;
public int age;
}
class Student extends Teacher{
private String name;
public int age;
}
Field类中常见的方法
setAccessible(true)//设置可以访问私有访问权限
set(object,value)
Class<Student> stu = Student.class;
//通过反射类获得对象的类对象
Student student = stu.newInstance();
//获取本类中指定的属性对象
Field name = stu.getDeclaredField("name");
System.out.println(name);
//设置可以访问私有访问权限
name.setAccessible(true);
name.set(student,"cjj");
System.out.println(student);
通过反射类获取方法类对象
获取本类以及父类中的所有public方法
反射类.getMethods()
获取本类以及父类中的指定public方法
反射类.getMethod("方法名",参数类型)
获取本类中指定的方法
反射类.getDeclaredMethod(方法名,参数类习性)
获取本类中的所有方法
反射类.getDeclaredMethods()
获取本类中指定的方法,有参就需要加上参数类型
Method select = student.getDeclaredMethod("select",int.class)
public class Test {
public static void main(String[] args) throws Exception {
Class<Student> student = Student.class;
Student student1 = student.newInstance();
//获取本类以及父类中的所有方法
Method[] methods = student.getMethods();
for (Method method : methods) {
System.out.println(method);
}
}
}
class Student{
private String name;
public int age;
public void select(){
System.out.println("查询所有学生");
}
}
Method类中常见的方法
invoke 运行指定的方法
public class Test {
public static void main(String[] args) throws Exception {
Class<Student> student = Student.class;
Student student1 = student.newInstance();
//获取本类中指定的方法
Method select = student.getDeclaredMethod("select",int.class);
//运行该方法
Object invoke = select.invoke(student1, 10);
System.out.println(invoke);
}
}
class Student{
private String name;
public int age;
public String select(int i){
System.out.println("查询所有学生");
return ""+i;
}
}
通过反射类获取构造方法对象
获取本类以及父类中指定的public构造方法
反射类.getConstructor(有参就加上类型)
获取本类以及父类中所有的public构造方法
反射类.getConstructors()
获取本类中所有的构造方法
反射类.getDeclaredConstructors()
获取本类中指定的构造方法
反射类.getDeclaredConstructor(有参就加上类型)
public class Test {
public static void main(String[] args) throws Exception {
//得到反射类对象
Class<Student> student = Student.class;
//getConstructor()获取无参构造函数
Constructor<Student> constructor = student.getConstructor();
//通过无参构造函数获取到相应的实例对象
Student student1 = constructor.newInstance();
System.out.println(student1);
//getConstructor()获取有参构造函数
Constructor<Student> constructor1 = student.getConstructor(String.class, int.class);
//通过有参构造函数获取到相应的实例对象,并赋值
Student student2 = constructor1.newInstance("cjj",21);
System.out.println(student2);
}
}
class Student{
private String name;
public int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
}
通过类反射获取类上的注解
获取本类以及父类上的所有注解
反射类.getAnnotations()
获取本类以及父类上的指定注解
反射类.getAnnotation(注解名.class)
获取本类上的指定注解
反射类.getDeclaredAnnotation(注解名.class)
获取本类上的所有注解
反射类.getDeclaredAnnotations()
public class Test {
public static void main(String[] args) {
Class<Student> student = Student.class;
Annotation[] declaredAnnotations = student.getAnnotations();//拿到本类以及父类的所有注解
System.out.println(Arrays.asList(declaredAnnotations));
}
}
@ZuJie("cjj")
class Student{
}
@Retention(RetentionPolicy.RUNTIME)//运行时有效
@interface ZuJie{
String value();
}
通过注解对象操作注解中相关的属性
注解反射对象.注解属性名 //拿到注解中指定属性的值
public class Test {
public static void main(String[] args) {
Class<Student> student = Student.class;
ZuJie declaredAnnotation = student.getDeclaredAnnotation(ZuJie.class);
String value = declaredAnnotation.value();//拿到注解里面的值
System.out.println(value);
}
}
@ZuJie("cjj")
class Student{
}
@Retention(RetentionPolicy.RUNTIME)//运行时有效
@interface ZuJie{
String value();
}