当前位置: 代码迷 >> 综合 >> 【JAVASE(7)】JAVASE学习--注解及小众常用类篇
  详细解决方案

【JAVASE(7)】JAVASE学习--注解及小众常用类篇

热度:83   发布时间:2023-11-30 15:06:47.0

A、注解--Annotation
    一、概念:
        注释:文字描述程序,给人看
        注解:说明程序,给计算机看

        1)从JDK5开始,Java增加对元数据的支持(MetaData),也就是注解(Annotation)。
        2)注解与注释是有一定区别的,可以把注解理解为代码里的特殊标记,这些标记可以在编译,类加载,运行时被读取,并执行相应的处理。
        3)通过注解开发人员可以在不改变原有代码和逻辑的情况下在源代码中嵌入补充信息。代码分析工具,开发工具和部署工具可以通过这些补充信息进行验证或者进行部署。
        4)Annotation可以像修饰符一样被使用,可用于修饰包类,构造器,方法,成员变量,参数,局部变量的声明,这些信息被保存到Annotation的“name=value”中
        5)框架=注解+反射+设计模式
        6)通过反射获取注解信息

    二、概念描述:
        jdk1.5后的新特性
        说明程序
        使用注解:@注解名称

    三、作用分类:
        1.编写文档:API文档。即生成文档相关的注解
        2.代码分析:跟踪代码依赖性,实现替代配置文件功能
        3.编译检测:在编译时进行格式检查(jdk内置的三个基本注解)
            @Override:限定重写父类方法,该注解只能用于方法
            @Deprecated:用于不考试所修饰的元素(类、方法)已经过时。通常因为所修饰的结构危险或存在更好的选择
            @SuppressWarning:压制编译器警告


            

    四、JDK中预定义的注解
        1.@Override:检测被该注解注释的方法是否值继承自父类接口的。限定重写父类方法,该注解只能用于方法
        2.@Deprecated:该注解标注的内容已经过时。用于不考试所修饰的元素(类、方法)已经过时。通常因为所修饰的结构危险或存在更好的选择
        3.@SuppressWarnings:压制警告,一般传递参数all:@SuppressWarnings("all")
        4.@SafeVarargs
        5.@FunctionalInterface

    五、自定义注解
        1、格式:

            元注解public @interface 注解名称{ 属性列表 }

        2、本质:注解本质上就是一个接口,该接口默认继承java.long.annotation.Annotation接口

 public interface MyAnnotation extends java.long.annotation.Annotation{}

        3、属性:接口中可以定义的抽象方法
            要求:
                1.属性的返回值类型只有以下几种:
                        基本数据类型:4类8种
                        String
                        枚举
                        注解
                        以上类型的数组

                2.定义了属性,在使用时需要给属性赋值
                    1.若定义属性是使用了default关键字给属性默认初始化值,则使用注解时,可以不进行属性的赋值。即可以指定成员的默认值,使用default定义
                    2.若只有一个属性需要赋值,并且属性的名称是value,那么value可以省略,直接定义值即可。即内部定义成员(其中成员变量的定义形式与方法的定义形式相同)通常使用value
                    3.数组赋值时值使用{}包裹,若数组中只有一个值则{}可以省略
                    4.若自定义注解无成员,表明是一个标识作用;若注解有成员,在使用注解时,需要指明成员的值。自定义注解必须配上注解的信息处理流程(使用反射)才有意义。自定义注解一般都会指明两个元注解:@Retention、@Target和@Inherited等

    六、元注解:
        1.概念:
            用于描述注解的注解。对现有的注解进行解释说明的注解;类比元数据{对现有数据修饰的数据}
        2.jdk提供的4种元注解说明:
            @Target:描述注解能够作用的位置。即用于指定被修饰的Annotation能用于修饰哪些元素

                ElementType取值:TYPE:可以作用于类上;表示class,interface,enumMETHOD:可以作用于方法上FIELD:可以作用于成员变量上PARAMETER:表示参数CONSTRUCTOR:表示构造器LOCAL_VARIABLE:表示局部变量

            @Retention:描述注解被保留的阶段;即指定所修饰的Annotation的生命周期。

                SOURCE{声明为SOURCE生命周期的注解,不会保留到.class文件中}CLASS{默认行为,编译的时候存在,运行的时候不会加载到内存}RUNTIME{只有声明为RUNTIME生命周期的注解,才能通过反射获取}例如:@Retention(RetentionPolicy.RUNTIME):当前被描述的注解,会遍历到class字节码文件中,并被JVM读取到

            @Documented:描述注解是否被抽取到API文档
                添加注解后,被描述的注解就被抽取在api文档中。表示所修饰的注解在被javadoc解析时,保留下来

            @Inherited:描述注解是否被子类继承
                被它修饰的Annotation具有继承性


    七、在程序中使用(解析)注解:获取注解中定义的属性值
        1.获取注解定义位置的对象(CLASS,METHOD,FIELD)
        2.获取指定的注解:getAnnotation(Class)
        3.调用注解中的抽象方法获取配置的属性值
            在内存中生成了一个该注解接口的子类实现对象

public class ProImpl implements Pro(){public String className(){return "全路径.Demo"}public String methodName(){return "pri"}
}

    小节:
        1.大多数时候是使用注解而非自定义注解
        2.注解使用者:注解给编译器、解析程序使用
        3.注解不是程序的一部分,可以理解为注解就是一个标签
        4.如何获取注解信息:以此注解的原注解Retention中声明的声明周期状态为:RUNTIME为前提,通过反射来进行获取、调用


    八、jdl8中注解的新特性:可重复注解、类型注解
        可重复注解:
            1)在目标注解1中声明@Repeatable(目标注解2.class)将目标注解1和目标注解2相互关联
            2)将目标注解2中的成员变量声明为目标注解1的数组形式
            3)目标注解1的@Retention、@Target和@Inherited等与目标注解2相同
        类型注解:
            ElementType.TYPE_PARAMETER:表示该注解能些在练习变量的声明语句中(如:泛型声明)
            ElementType.TYPE_USE:表示该注解能写在使用类型的任何语句中

B、用于比较的两个接口:
    一、java中的对象,正常情况下,只能进行比较:==或!=,不能使用>或<的比较,但在开发场景中,需要多多个对象进行排序,即需要比较对象的大小,此时就需要使用两个接口{Comparable或Comparator}中的任意一个进行实现

    二、Comparable接口的使用(自然排序):
        1.像String、包装类等实现类Comparable接口,重写CompareTo(obj)方法,给出了比较两个对象大小的方式
        2.像String、包装类重写CompareTo(obj)方法以后,进行了从小到大的排列
        3.重写CompareTo(obj)方法的规则:

            若当前对象this大于形参对象obj时,则返回正整数,若当前对象this小于形参对象obj时,则返回负整数,若当前对象this等于形参对象obj时,则返回0。

         4.对于自定义类来说,如果需要排序,可以让自定义类实现comparable接口,重写compareTo(obj)方法,在compareTo(obj)中指明如何排序;其中在jdk1.8之前实现compare接口时可以不加泛型,那么在实现compareTo(obj)方法时要先做instanceof判断类型,在判断好类型之后,重写比较规则,同时还有考虑传入数据有问题的抛出运行时异常的情况;在jdk1.8以后,要在实现compare接口时加泛型,在重写compareTo(obj)就不必进行instanceof判断类型

    三、Comparator接口的使用(定制排序):
        1.背景:当元素的类型没有实现java.lang.Comparable接口而又不方便修改代码,或者实现了java.lang.Comparable接口的排序规则不适合当前的操作,那么可以考虑使用Comparator的对象来排序
        2.重写compare(Object o1,Object o2)方法,比较o1和o2的大小:若返回正整数则表示o1大于o2;若返回0表示二者同大小;若返回负数则表示o1小于o2

    四、Comparator接口与Comparable接口的对比:
        Comparable接口的方式一旦指定,保证Comparable接口实现类的对象在任何位置都可以比较大小Comparator接口属于临时性的比较大小。

        Comparator和Comparable的区别
                Comparable:自己(this)和别人(参数)比较,自己需要实现Comparable接口,重写CompareTo方法
                Comparator:相当于找一个第三方裁判,比较两个


C、其他常用类的使用
    一、System
        public.long.System类提供了大量静态方法,可以获取与系统相关的信息或系统级操作,常用方法(包含标准的输入流,输出流,错误提示等)

getProperty()方法可以得到有关系统何java的基本信息
public static long currentTimeMillis();返回以毫秒为单位的当前时间
public static void arrayCopy(Object src,int srcPos,Object dest,int srcPos,int length
):将数组中指定的数据类型拷贝到另外一个数组中其中参数:src:源数组srcPos:源数组当中的起始值dest:目标数组destPos:目标数组中的起始位置length:要复制的数组元素的数量


    二、Math
        与数学相关的类
        java.util.Math类是数学相关的工具类,里面提供了大量的静态方法,完成与数学运算相关的操作。

            public static double abs(double num):得到绝对值,有多种重载;public static double ceil(double num):向上取整;12.1取值13public static double floor(double num):向下取整;12.9取值12public static long round(double num):四舍五入;


    三、BigInteger 和 BigDecimal
        BigInteger表示大整型
        BigDecimal表示大浮点型

    四、枚举类
        1、枚举类的使用:
            1.枚举类的理解:类的对象只有确定的有限个。则称此类为枚举类
            2.当需要定义一组常量时,使用枚举类
            3.若枚举类中只有一个对象,则可以作为单列模式的实现方式

        2、如何定义枚举类:
            方式一:jdk5.0之前,自定义枚举类
            方式二:jdk5.0,可以使用enum关键字定义枚举类

        3、Enum类中的常用方法
           values()方法:返回枚举类型的对象数组。该方法可以衡方便地遍历所有的枚举值
           valueOf(String str)方法:返回枚举类中对象名称是传入参数的对象,若不存在此对象就会抛出运行时异常:IllegalArgumentException
           toString()方法:返回当前枚举类对象常量的名称

       4、使用enum关键字定义的枚举类实现接口的情况
           情况一:实现接口,在enum类中实现抽象方法
           情况二:让枚举类的对象分别实现接口中的抽象方法


       5、使用enum关键字定义枚举类
           说明:定义的枚举类默认继承于java.lang.Enum类

        6、自定义枚举类实例一:

public class SeasonTest {public static void main(String[] args) {Season spring = Season.SPRING;System.out.println(spring);}
}//自定义枚举类
class Season{//1.声明Season对象的属性,print final修饰private final String seasonName;private final String seasonDesc;//2.私有化类的构造器,并且给对象属性赋值private Season(String seasonName,String seasonDescc){this.seasonName=seasonName;this.seasonDesc=seasonDescc;}//3.通过当前枚举类的多个对象,public static finalpublic static final Season SPRING =new Season("春天","春暖花开");public static final Season SUMMER =new Season("夏天","酷热难耐");public static final Season AUTUMN =new Season("秋天","秋高气爽");public static final Season WINTER =new Season("冬天","下雪了");//4.其他诉求1,获取枚举类对象的属性public String getSeasonName() {return seasonName;}public String getSeasonDesc() {return seasonDesc;}//4.其他诉求2,提供toString方法@Overridepublic String toString() {return "Season{" +"seasonName='" + seasonName + '\'' +", seasonDesc='" + seasonDesc + '\'' +'}';}
}

        自定义枚举类二:

/*使用enum关键字定义枚举类说明:定义的枚举类默认继承于java.lang.Enum类*/
public class SeasonTest {public static void main(String[] args) {Season summer = Season.SUMMER;//toString()System.out.println(summer.toString());
//        System.out.println(Season.class.getSuperclass());System.out.println("*************************************************");//values()方法Season[] values = Season.values();for (Season value : values) {System.out.println(value);value.show();}System.out.println("*************************************************");Season autumn = Season.valueOf("AUTUMN");System.out.println(autumn);autumn.show();}
}interface info{void show();
}//使用enum关键字
enum  Season implements info{//1.通过当前枚举类的对象,多个对象间用“,”隔开,末尾对象用“;”结束SPRING ("春天","春暖花开"){@Overridepublic void show() {System.out.println("你好春天");}},SUMMER ("夏天","酷热难耐"){@Overridepublic void show() {System.out.println("你好夏天");}},AUTUMN ("秋天","秋高气爽"){@Overridepublic void show() {System.out.println("你好秋天");}},WINTER ("冬天","下雪了"){@Overridepublic void show() {System.out.println("你好冬天");}};//2.声明Season对象的属性,print final修饰private final String seasonName;private final String seasonDesc;//3.私有化类的构造器,并且给对象属性赋值private Season(String seasonName,String seasonDescc){this.seasonName=seasonName;this.seasonDesc=seasonDescc;}//4.其他诉求1,获取枚举类对象的属性public String getSeasonName() {return seasonName;}public String getSeasonDesc() {return seasonDesc;}//4.其他诉求2,提供toString方法@Overridepublic String toString() {return "B0P1D3Season01{" +"seasonName='" + seasonName + '\'' +", seasonDesc='" + seasonDesc + '\'' +'}';}//    @Override
//    public void show() {
//        System.out.println("这是一个季节");
//    }
}

D、关于IDEA中的DEBUG调试:

DeBug调试程序:
        可以让代码逐行执行,查看代码执行过程,调试程序中出现的bug

    使用:
        在行号右边加断点,右键选择D额bug执行,程序会停在断点处

    执行程序:
        f8逐行执行程序
        f7进入方法
        shift+f8跳出方法
        f9跳到下一个断点,若无断点就结束程序
        ctrl+f2退出debug模式结束程序
        Console切换控制台


、递归:
    递归:方法自己调用自己
        递归的分类:
            直接:方法自身调用自己
            间接:A方法调用B方法,B方法调用C方法,C方法调用A方法

        注:
            递归一定要有限制条件,保证递归能够停下来,否则发生栈内存溢出
            在递归中虽然有限定条件,但递归次数不能太多,否则发生栈内存溢出
            构造方法禁止递归
        递归使用前提:
            当调用方法时,方法主体不变,每次调用方法的参数不同,可以使用递归

    递归计算1-n之间的和;
        注:
            使用递归求和,main方法调用sum方法,sum方法会一直调用sum方法,导致内存中有多个sum方法(频繁的创建方法,调用方法,销毁方法)效率低下。所以若仅仅是计算1-n之间的和,不推荐递归方法使用for循环即可。

以上是本篇小节,不喜勿喷,感谢理解

相关链接:

【JAVASE(8)】JAVASE学习--集合篇一(集合概述)_lixxkv的博客-CSDN博客
【JAVASE(6)】JAVASE学习--字符串篇_lixxkv的博客-CSDN博客

  相关解决方案