2021-08-25

本文详细介绍了Java中的注解和反射机制。首先讲解了注解的基本概念、内置注解、元注解以及如何自定义注解。接着,深入探讨了反射的使用,包括获取反射对象、Class类的多种获取方式、反射获取类的结构以及动态创建对象和调用方法。此外,还展示了通过反射操作属性的示例。内容覆盖了注解的生命周期、目标位置以及反射在程序动态性中的关键作用。
摘要由CSDN通过智能技术生成

注解和反射

注解

什么是注解

Annotation是从jdk5.0开始引入新技术

作用:可对程序做出解释,可以被其他程序(比如:编译器等)读取。

格式:注解是以@注释名在代码中存在的

可以通过反射读注解

内置注解

  • @override 重写超类(父类)方法声明

  • @Deprecated 危险,已过时的

  • @SupperWarning 抑制编译时的警告信息

元注解

元注解的作用就是负责注解其他注解。

  • @Target: 被描述的注解可以放在什么地方(例如方法上,类上)
@Target(value = {ElementType.METHOD,ElementType.TYPE})
  • @Retention:描述注解的生命周期
@Retention(value = RetentionPolicy.RUNTIME)
  • @Document:说明该注解被包含在javadoc中
  • Inherited:说明自雷可以继承父类中的该注解

自定义注解

  • 使用@interface自定义注解时,自动继承了java.lang.annotation.Annotation接口

  • 分析:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-o61Zr9X2-1629878413311)(D:\File\图片\QQPhoto\QQ截图20210825153712.png)]

    //自定义注解
    public class Test3 {
        //注解可以显示赋值,如果没有默认值,我们就必须给赋值
        @MyAnnotiation2(age = 18,name = "秦疆")
    
        public void  test(){
        }
        @MyAnnotation3("QINJIANG") //如果注解只有一个值,可用value命名,省略value=
        public void  test1(){
        }
    }
    @Target({ElementType.TYPE,ElementType.METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    @interface MyAnnotiation2{
        //注解的参数:参数类型+参数名()
        String name() default "";
        int age();
        int id() default -1;//如果默认值是-1,代表不存在
        String[] schools() default {"西部开源","清华大学"};
    }
    @interface MyAnnotation3{
        String value();
    }
    

反射

反射是java被视为动态语言的关键。

优点:实现动态创建对象和编译

缺点:对性能有影响

1、获得反射对象

Class c = Class.forName(“java.lang.String”)

一个类在内存中只有一个class对象,这个类包含了完整的类的结构信息。

在这里插入图片描述
反射相关的API
在这里插入图片描述

2、获得Class类的几种方式

Class类的常用方法
在这里插入图片描述
获取Class类的实例
在这里插入图片描述

        //方式一:通过对象过得到
        Class c1 = person.getClass();
        System.out.println(c1.hashCode());
        System.out.println(c1.getName());
        //方式二:forname获得
        Class c2 = Class.forName("com.jia.reflection.Student");
        System.out.println(c2.hashCode());
        System.out.println(c2.getName());
        //方式三: 通过类名.class获得
        Class<Student> c3 = Student.class;
        System.out.println(c3.hashCode());
        System.out.println(c3.getName());

3、获取运行时类的完整结构

通过反射获取运行时类的完整结构

Field、Method、Constructor、SuperClass、Interface、Annotation在这里插入图片描述

        //获得类的名子
        System.out.println(c1.getName());//获得包名+类名
        System.out.println(c1.getSimpleName());//获得类名
        //获得类的属性
        Field[] fields = c1.getFields();  //getFileds()只能找到public属性
        fields= c1.getDeclaredFields();//getDeclaredFields()能找到全部属性
        for (Field field : fields) {
            System.out.println(field);
        }
        Field name = c1.getDeclaredField("name");//获得指定属性
        System.out.println(name);
  • 获得类的方法

    • getMethods() :获得本类及其父类的全部public方法

    • getDeclaredMethods() :获得本类的所有方法

    • getMethod(name,parameterTypes) :获得指定方法 例如:

      c1.getMethod("setName",String.class);
      

4、动态创建对象执行

(1)创建类的对象:调用Class对象的newInStance()方法

​ 类必须有一个无参数的构造器

​ 类的构造器访问权限需要足够

**注:**如果没有无参构造器,只要在操作是明确调用类的构造器,并将参数穿进去,才可以实例化。步骤如下:

  • 通过Class类的getDeclaredConstructor(Class …parameterType)取得本类的指定形参类型的构造器。
  • 按构造器的需要,里面放入构造器所需的各个参数
  • 通过Constructor实例化对象。
//动态创建对象,通过反射
public class Test2 {
    public static void main(String[] args) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, ClassNotFoundException {
        //获得Class对象
        Class c1 = Class.forName("com.jia.reflection.User");
        //构造一个对象
        User user = (User)c1.newInstance(); //本质是调用了类的无参构造器
        System.out.println(user);
        
        //通过有参构造器创建对象
        Constructor constructor = c1.getDeclaredConstructor(String.class, int.class, int.class);
        User user2 = (User) constructor.newInstance("秦疆",2,18);
        System.out.println(user2);
    }
}

(2)调用指定得到方法

通过反射,调用类中的方法,通过Method类完成

  • 通过Class类的getMethod(String name, Class…parameterType)方法取得一个Method对象,并设置此方法操作时所需的参数类型。
  • 之后使用 Object invoke(Object obj, Object[] args)(对象,方法值)进行调用,并向方法中传递设置的obj对象的参数信息。

Object invoke(Object obj, Object[] args)
在这里插入图片描述

        //通过反射调用普通方法
        User user3 = (User)c1.newInstance();
        //通过反射获取一个方法
        Method setName = c1.getMethod("setName", String.class);
        //invoke:激活的意思
        //(对象,"方法的值")
        setName.invoke(user3,"狂神");
        System.out.println(user3.getName());

(3)通过反射操作属性

        //通过反射操作属性
        User user4 = (User)c1.newInstance();
        Field name = c1.getDeclaredField("name");
        //不能直接操作私有属性,我们需要关闭程序的安全监测,属性或者方法的setAccessible(true)
        name.setAccessible(true);
        name.set(user4,"狂神2");
        System.out.println(user4.getName());

setAccessible
在这里插入图片描述

视频连接:https://www.bilibili.com/video/BV1p4411P7V3?p=4

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是将XML转换为.NET Core实体模型的代码示例: ```csharp using System.Xml.Serialization; [XmlRoot(ElementName = "OTA_InventoryCheckRS")] public class InventoryCheckResponse { [XmlAttribute(AttributeName = "TimeStamp")] public string TimeStamp { get; set; } [XmlAttribute(AttributeName = "Version")] public string Version { get; set; } [XmlAttribute(AttributeName = "EchoToken")] public string EchoToken { get; set; } [XmlElement(ElementName = "HotelResult")] public HotelResult HotelResult { get; set; } } public class HotelResult { [XmlElement(ElementName = "HotelID")] public string HotelID { get; set; } [XmlElement(ElementName = "HotelProducts")] public HotelProducts HotelProducts { get; set; } } public class HotelProducts { [XmlElement(ElementName = "HotelProduct")] public HotelProduct HotelProduct { get; set; } } public class HotelProduct { [XmlElement(ElementName = "FreeCancelable")] public FreeCancelable FreeCancelable { get; set; } [XmlElement(ElementName = "RoomTypes")] public RoomTypes RoomTypes { get; set; } [XmlElement(ElementName = "RatePlans")] public RatePlans RatePlans { get; set; } [XmlElement(ElementName = "Prices")] public Prices Prices { get; set; } } public class FreeCancelable { [XmlAttribute(AttributeName = "FreeCancelableVal")] public string FreeCancelableVal { get; set; } } public class RoomTypes { [XmlElement(ElementName = "RoomType")] public RoomType RoomType { get; set; } } public class RoomType { [XmlAttribute(AttributeName = "RoomTypeCode")] public string RoomTypeCode { get; set; } } public class RatePlans { [XmlElement(ElementName = "RatePlan")] public RatePlan RatePlan { get; set; } } public class RatePlan { [XmlAttribute(AttributeName = "RatePlanCode")] public string RatePlanCode { get; set; } } public class Prices { [XmlElement(ElementName = "Price")] public Price Price { get; set; } } public class Price { [XmlElement(ElementName = "Base")] public Base Base { get; set; } } public class Base { [XmlAttribute(AttributeName = "EffectDate")] public string EffectDate { get; set; } [XmlAttribute(AttributeName = "SalePrice")] public string SalePrice { get; set; } [XmlAttribute(AttributeName = "BasePrice")] public string BasePrice { get; set; } [XmlAttribute(AttributeName = "Allotment")] public string Allotment { get; set; } [XmlAttribute(AttributeName = "DcOverSaleAllotment")] public string DcOverSaleAllotment { get; set; } [XmlAttribute(AttributeName = "DcAddAllotment")] public string DcAddAllotment { get; set; } [XmlAttribute(AttributeName = "DcContractAllotment")] public string DcContractAllotment { get; set; } [XmlAttribute(AttributeName = "DcBuyOutAllotment")] public string DcBuyOutAllotment { get; set; } } ``` 在调用方代码中,您可以使用以下代码将XML转换为.NET Core实体模型: ```csharp string xml = "<OTA_InventoryCheckRS TimeStamp=\"1629879848173\" Version=\"1.000\" EchoToken=\"18029461-194a-4c7e-b372-6eec346cebd4\"> <HotelResult> <HotelID>10000007</HotelID> <HotelProducts> <HotelProduct> <!--只有支持30分钟免费取消的酒店,才需要返回该节点--> <FreeCancelable FreeCancelableVal=\"true\" /> <RoomTypes> <RoomType RoomTypeCode=\"2106\"/> </RoomTypes> <RatePlans> <RatePlan RatePlanCode=\"302-4529\"/> </RatePlans> <Prices> <Price> <Base EffectDate=\"2021-08-25\" SalePrice=\"515.2\" BasePrice=\"515.2\" Allotment=\"53\" DcOverSaleAllotment=\"53\" DcAddAllotment=\"-1\" DcContractAllotment=\"-1\" DcBuyOutAllotment=\"-1\"/> </Price> </Prices> </HotelProduct> </HotelProducts> </HotelResult> </OTA_InventoryCheckRS>"; XmlSerializer serializer = new XmlSerializer(typeof(InventoryCheckResponse)); using StringReader reader = new StringReader(xml); InventoryCheckResponse response = (InventoryCheckResponse)serializer.Deserialize(reader); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值