JAVA基础——反射和注解

  • 反射
    • 获取Class对象的三种方式
    • 反射创建类对象
    • 反射获取field
    • 反射获取method
    • 反射获取constructor
    • 反射获取泛型
    • 反射获取注解
  • 注解
    • jdk的3个内置注解
    • 5个元注解:@Retention,@Target ...
    • 注解的属性
    • 注解的本质:Annotation接口的子接口

1. 反射概念

  • 反射:在程序运行期,对于任意一个类,都能动态获取和调用它的所有方法和属性。

(1) 获取Class对象的方式(3种)

//1.Class类的静态方法+全限类名
Class cls1 = Class.forName("company.group.name.Person");
//2.类名.class
Class cls2 = Person.class;
//3.Object类中的getClass()
Person p = new Person();
Class cls3 = p.getClass();

(2)反射创建类对象(2种)

  • Class的newInstance方法底层还是调用 无参构造器的newInstance()方法
  • 如果该类没有无参构造器或者不是public,Class.newInstance()无法使用,会有异常
Person p = new Person();
Class cls = p.getClass();

//1.利用Class自带的newInstance()
Person p1 = (Person)cls.newInstance();

//2.先获取构造器,再创建对象
Constructor con1 = cls.getConstructor(); //调用无参
Person p2 = (Person)con1.newInstance();

Constructor con2 = cls.getConstructor(String.class, int.class); //调用有参
Person p2 = (Person)con2.newInstance(“李四”,25);

(3)反射获取field

  • getFields()无法获取私有属性,只能获取 public属性 + 父类属性
  • getDeclaredFields() 可以获取包括private在内的所有自定义属性(仅仅获取属性名,无法获取值或修改值)
  • field.setAccessible(true):可以对private的get和set操作
Field getField(String name) //获得命名的公共字段 
Field[] getFields() //获得类的所有公共字段 
Field getDeclaredField(String name) //获得类声明的命名的字段 
Field[] getDeclaredFields() //获得类声明的所有字段

//例子
Class cls = Person.class;
Field f = cls.getField("name");

Person p = new Person("张三",25);
Object value = f.get(p);
f.set(p, “李四”);

(4)反射获取方法

  • 调用Method类的invoke()方法
Method getMethod(String name, Class[] params) //(方法名,参数1,参数2...)
Method[] getMethods() //获得类的所有public方法 + 父类方法
Method getDeclaredMethod(String name, Class[] params) //所有修饰符的方法(不含父类)
Method[] getDeclaredMethods() //所有方法(不含父类)

Class cls = Person.class;
Method eat1 = cls.getClass("eat")   // 获取eat()方法
Method eat2 = cls.getClass("eat",String.class)  //获取eat(String name)方法

Person p = new Person();
eat1.invoke(p);     //执行p的eat()方法
eat2.invoke(p, "大饼");       //执行p的eat("大饼")方法
String name = eat1.getName();     //获取"eat"

(5)反射获取构造器

Constructor getConstructor(Class[] params)  //(参数1,参数2...)
Constructor[] getConstructors() 
Constructor getDeclaredConstructor(Class[] params)  //所有修饰符的构造器
Constructor[] getDeclaredConstructors() //所有修饰符的构造器

Class cls = Person.class;
Constructor con1 = cls.getConstructor();
Constructor con2 = cls.getConstructor(String.class, int.class);
Person per1= (Person)con1.newInstance();
Person per2= (Person)con2.newInstance(“张三”, 25);

(6)反射获取泛型

  •  

(7)反射获取注解

  • getAnnotation() 和 getDeclaredAnnotation()方法

2. 注解

  • 注解作用
    • 编写API文档:代码里进行注释,javadoc命令生成对应的API文档
    • 编译检查:如Override检查
    • 代码分析:反射
  • 注解本质
public @interface MyTestAnnotation {}

(1)JDK内置注解,没啥大用处

@Override:检测该方法是否是继承自父接口
@Deprecated:标注该内容已过时,不建议使用
@SuppressWarnings:压制警告,例如在eat()方法上加上该注解,关于该方法编译阶段的警告(如never used)都不会出现

(2)元注解(5种):用来修饰注解的注解

  • @Retention:它表示注解存在阶段是保留在源码(编译期),字节码(类加载)或者运行期(JVM中运行)
//@Retention(RetentionPolicy.SOURCE),注解仅存在于源码中,在class字节码文件中不包含
//@Retention(RetentionPolicy.CLASS), 默认的保留策略,注解会在class字节码文件中存在,但运行时无法获得
//@Retention(RetentionPolicy.RUNTIME), 注解会在class字节码文件中存在,在运行时可以通过反射获取到
//注:自己定义的注解一般都用RUNTIME
@Retention(RetentionPolicy.RUNTIME)
public @interface MyTestAnnotation {

}
  • @Target:它表示我们的注解作用的范围,可以是类,方法,方法参数变量等
//@Target(ElementType.TYPE) 作用接口、类、枚举、注解
//@Target(ElementType.FIELD) 作用属性字段、枚举的常量
//@Target(ElementType.METHOD) 作用方法
//@Target(ElementType.PARAMETER) 作用方法参数
//@Target(ElementType.CONSTRUCTOR) 作用构造函数
//@Target(ElementType.ANNOTATION_TYPE)作用于注解(@Retention注解中就使用该属性)
//一般比较常用的是ElementType.TYPE类型
@Target(ElementType.TYPE)
public @interface MyTestAnnotation {

}
  • @Documented:它的作用是能够将注解中的元素包含到 Javadoc 中去
  • @Inherited:表示它的子类也继承了父类的注解
  • @Repeatable(JDK1.8加入):这个元注解修饰的注解可以同时作用一个对象多次,但是每次作用注解又可以代表不同的含义,见Reference

(3)注解的属性

  • 可以有以下类型
    • 8种基本数据类型
    • String
    • 枚举类
    • 注解类
    • Class类
    • 以上类型的一维数组类
  • 可以用default关键字设置初始化值,数组赋值时,可以用{}
  • 如果只有一个属性需要赋值,且名称是value,则可以省略不写
@Documented
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface MyTestAnnotation {
    String name() default "mao";
    int age() default 18;
}

@MyTestAnnotation(name = "father", age = 50)
public class Father {
}

(4)注解的本质:Annotation接口的子接口

本质:继承Annotation接口的子接口
public interface 注解名称 extends java.lang.annotation.Annotation{}

/**Annotation接口源码*/
public interface Annotation {
    boolean equals(Object obj);
    int hashCode();
    Class<? extends Annotation> annotationType();
}

Reference

注解:https://www.jianshu.com/p/9471d6bcf4cf

反射:https://blog.csdn.net/qq_36226453/article/details/82790375

 


2.4 注解与反射

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
本火锅店点餐系统采用Java语言和Vue技术,框架采用SSM,搭配Mysql数据库,运行在Idea里,采用小程序模式。本火锅店点餐系统提供管理员、用户两种角色的服务。总的功能包括菜品的查询、菜品的购买、餐桌预定和订单管理。本系统可以帮助管理员更新菜品信息和管理订单信息,帮助用户实现在线的点餐方式,并可以实现餐桌预定。本系统采用成熟技术开发可以完成点餐管理的相关工作。 本系统的功能围绕用户、管理员两种权限设计。根据不同权限的不同需求设计出更符合用户要求的功能。本系统中管理员主要负责审核管理用户,发布分享新的菜品,审核用户的订餐信息和餐桌预定信息等,用户可以对需要的菜品进行购买、预定餐桌等。用户可以管理个人资料、查询菜品、在线点餐和预定餐桌、管理订单等,用户的个人资料是由管理员添加用户资料时产生,用户的订单内容由用户在购买菜品时产生,用户预定信息由用户在预定餐桌操作时产生。 本系统的功能设计为管理员、用户两部分。管理员为菜品管理、菜品分类管理、用户管理、订单管理等,用户的功能为查询菜品,在线点餐、预定餐桌、管理个人信息等。 管理员负责用户信息的删除和管理,用户的姓名和手机号都可以由管理员在此功能里看到。管理员可以对菜品的信息进行管理、审核。本功能可以实现菜品的定时更新和审核管理。本功能包括查询餐桌,也可以发布新的餐桌信息。管理员可以查询已预定的餐桌,并进行审核。管理员可以管理公告和系统的轮播图,可以安排活动。管理员可以对个人的资料进行修改和管理,管理员还可以在本功能里修改密码。管理员可以查询用户的订单,并完成菜品的安排。 当用户登录进系统后可以修改自己的资料,可以使自己信息的保持正确性。还可以修改密码。用户可以浏览所有的菜品,可以查看详细的菜品内容,也可以进行菜品的点餐。在本功能里用户可以进行点餐。用户可以浏览没有预定出去的餐桌,选择合适的餐桌可以进行预定。用户可以管理购物车里的菜品。用户可以管理自己的订单,在订单管理界面里也可以进行查询操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值