Java基础(二十三)——Stream流、枚举、注解、自定义注解、元注解

Java基础(二十三)——Stream流、枚举、注解、自定义注解、元注解

一、Stream流

1、概念

Stream:是一个接口,功能类似于流水线的工作,主要就是用于对数据进行过滤。流(Stream)与集合类似,但集合中保存的是数据,而Stream中保存对集合或数组数据的操作。

作用:使用Stream对数据进行过滤,简化Java代码。

特点:

  • Stream 自己不会存储元素。
  • Stream 不会改变源对象。相反,他们会返回一个持有结果的新Stream。
  • Stream 操作是延迟执行的,会等到需要结果的时候才执行。

Stream,提供两类方法::延迟方法、终结方法。

延迟方法:表示是调用 Stream方法之后返回值还是,Stream对象,可以继续使用用Stream的方法。
终结方法::表示是调用 Stream方法之后返回值不是,Stream对象,不能再使用Stream的方法。

2、案例一

通过案例来理解:
Java基础(二十三)——Stream流、枚举、注解、自定义注解、元注解

3、获取 Stream 流的途径

Java基础(二十三)——Stream流、枚举、注解、自定义注解、元注解
Collection 及其子类能创建 Stream 流。Map 集合不行。

4、Stream 的方法

Java基础(二十三)——Stream流、枚举、注解、自定义注解、元注解

Java基础(二十三)——Stream流、枚举、注解、自定义注解、元注解

5、案例二

通过案例来了解用法。下面是需求:
Java基础(二十三)——Stream流、枚举、注解、自定义注解、元注解
实现代码:
Java基础(二十三)——Stream流、枚举、注解、自定义注解、元注解

二、枚举

1、概念

概念:用于表示一些固定的值的时候,就可以使用枚举来定义,枚举类中会定义一些枚举项,获取值的范围只能是枚举项。

格式:

	访问修饰符 enum 枚举的名称 { 枚举项 }

2、枚举注意的地方

  1. 每一个枚举类都是 Enum其子类。
  2. 每一个枚举项是一个类。
  3. 每一个枚举项,使用逗号进行分割,使用分号进行结尾(结尾可以不写分号,推荐使用)。
  4. 获取枚举项,直接通过 枚举类.枚举项就可以获取了。
  5. 枚举类中可以定义成员变量。
  6. 枚举项中可以存在构造方法,但是构造方法必须是私有的,默认也是私有的构造。
  7. 枚举类中可以存在抽象方法,每一个枚举项必须实现这个抽象方法。

枚举一般配合 switch 使用

3、练习

Java基础(二十三)——Stream流、枚举、注解、自定义注解、元注解

Java基础(二十三)——Stream流、枚举、注解、自定义注解、元注解

4、枚举常用的方法

Java基础(二十三)——Stream流、枚举、注解、自定义注解、元注解

三、注解

1、解释

注释:用于对代码进行解释说明,给程序员进行查看。

注解:用于对代码进行解释说明,给jvm(计算机)识别。

2、定义

注解(Annotation):也叫元数据。一种代码级别的说明。它是JDK1.5及以后版本引入的一个特性,
与类、接口、枚 举是在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前
面,用来对这些元素进行说明,注释。

3、作用分类

编写文档:通过代码里标识的元数据生成文档【生成文档doc文档】。
代码分析:通过代码里标识的元数据对代码进行分析【使用反射】。
编译检查:通过代码里标识的元数据让编译器能够实现基本的编译检查【Override】。

4、jdk 提供的注解

1.@Override:用于检查是否是重写父类的方法。

2.@Deprecated:用于标注方法是过时的方法 过时的方法可以使用 但是不建议使用。

3.@SuppressWarnings:压制黄色线警告。value = “all” 压制所有的黄色线警告。注解可以定义在类上 也可以定义方法上 也可以定义在属性上。

a、@Override——检查是否是重写父类的方法

先定义一个抽象类,然后里面定义抽象方法:
Java基础(二十三)——Stream流、枚举、注解、自定义注解、元注解

接着看其子类:
Java基础(二十三)——Stream流、枚举、注解、自定义注解、元注解
可以看到前面的注解。

如果改下方法名:
Java基础(二十三)——Stream流、枚举、注解、自定义注解、元注解

注解就出红线了。

b、@Deprecated——标注过时的方法

过时的方法可以使用,但不建议使用:

先定义一个过时的方法:
Java基础(二十三)——Stream流、枚举、注解、自定义注解、元注解

然后看看调用时:
Java基础(二十三)——Stream流、枚举、注解、自定义注解、元注解

可以看到,调用的时候划横线。但还是能调用:
Java基础(二十三)——Stream流、枚举、注解、自定义注解、元注解

c、@SuppressWarnings——压制黄线。

如果后面填写 value = “true”,则压制所有黄线:
Java基础(二十三)——Stream流、枚举、注解、自定义注解、元注解
看最右边,很多黄线。接着压制黄线看看:
Java基础(二十三)——Stream流、枚举、注解、自定义注解、元注解

现在,则一个都没有了。

四、自定义注解

1、使用前相关概念

1.格式组成:
	A.元注解
	B.public @interface Deprecated {}
	
2.注解本质:就是一个接口(下面那行通过反编译获得)
	public interface MyAnno extends java.lang.annotation.Annotation {}
	
3.接口中的成员:(只关注) 抽象方法 ==>属性

4.属性的返回值类型(必须有返回值,且返回值类型有限制。返回值不能是 void)
	A.基本数据类型 四类八种
	B.String 字符串类型
	C.枚举类型
	D.注解类型
	E.以上类型的数组类型
	
5.使用注解的语法: @注解的名称

6.注意点:
	A.使用的注解,必须给注解的所有的属性进行赋值,属性使用default设置默认值,可以不用进行赋值。
	B.使用注解,给属性的数组进行赋值的时候,只有一个值的情况,可以省略其大括号。
	C.如果注解的属性,只有一个value属性,在使用注解,进行赋值的时候,可以省略注解的名称。

2、练习自定义注解

可以看到,自定义注解能创建很多抽象方法(属性),所以这里尝试写一个自定义注解:

写一个注解,空白的:
Java基础(二十三)——Stream流、枚举、注解、自定义注解、元注解

接着定义一个注解,里面创建不同类型的属性:
Java基础(二十三)——Stream流、枚举、注解、自定义注解、元注解
接着写一个类,赋予注解:
Java基础(二十三)——Stream流、枚举、注解、自定义注解、元注解
因为注解必须有返回值,所以必须往里面填上返回值:
Java基础(二十三)——Stream流、枚举、注解、自定义注解、元注解
如果填上默认值,注解里就可以不用再赋值:
Java基础(二十三)——Stream流、枚举、注解、自定义注解、元注解

Java基础(二十三)——Stream流、枚举、注解、自定义注解、元注解

可以看到,这就是一个简单的自定义注解了。

五、元注解

1、元注解相关知识

1.元注解:用于描述注解的注解就是元注解。

2.元注解四个
	@Target:主要用于来表示注解作用的位置
		TYPE——作用域在类上
		FIELD——作用域在属性上
		METHOD——作用域在方法上
		
	@Retention:主要用于注解是否可以被识别
		RetentionPolicy.RUNTIME,程序在运行期间,生成Class字节码文件,定义注解会被jvm来识别。
		
	@Documented:用于标注是否在api文档上显示这个注解。
	
	@Inherited:用于表示注解是否继续被子类继承的使用。

2、案例一 ——使用注解与反射调用一个类的任意的方法

先定义注解:
Java基础(二十三)——Stream流、枚举、注解、自定义注解、元注解
可以看到,这个虽然是自定义注解,但是自定义注解上面还有元注解。

定义一个类,里面一个方法:
Java基础(二十三)——Stream流、枚举、注解、自定义注解、元注解

接着,就是主要代码:

@an1(className = "com.qf.cmf.An_lx3.Student",methodName = "method1")    //  在注解中填写包名类名。再注解中填写方法名
public class Demo1 {
    public static void main(String[] args)  {
        Class demo1class = Demo1.class;         //  获取当前这个类的类
        an1 an = (an1) demo1class.getAnnotation(an1.class); //  取当前这个类的注解
        an.className();     //  取出注解中的值(类名)
        an.methodName();    //  取出注解中的值(方法名)

        Class cls = Class.forName(an.className());  //  通过注解中的值反射获取 Student 类
        Constructor con = cls.getConstructor();     //  通过反射获取构造方法
        Object obj = con.newInstance();         //  实例化
        Method mt = cls.getMethod("method1");       //  通过类取出方法
        mt.invoke(obj);         //  然后调用此方法
    }
}

3、案例二 ——使用注解实现一个测试工具类

分析:
Java基础(二十三)——Stream流、枚举、注解、自定义注解、元注解

先来看这个注解:
Java基础(二十三)——Stream流、枚举、注解、自定义注解、元注解

接着看这个工具类:
Java基础(二十三)——Stream流、枚举、注解、自定义注解、元注解

最后来看主要代码:

public class Demo1 {
    public static void main(String[] args) throws IOException {
        BufferedWriter bw = new BufferedWriter(new FileWriter("error.txt"));    //  为后续写异常到文件里做准备

        int count = 0;      //  累计异常的个数
        TestUtils testUtils = new TestUtils();      //  先实例化工具类

        Class cla = testUtils.getClass();       //  通过对象反射获取类

        Method[] methods = cla.getMethods();       //   获取这个类的所有方法

        if (methods != null && methods.length>0){   //  数组非空验证
            for (Method m:methods) {
                if (m.isAnnotationPresent(an4.class)){      //  判断方法是否有 an4 这个注解。如果有就为 true。
                    try {
                        m.invoke(testUtils);        //  调用方法
                    }catch (Exception e){
                        bw.write("----开始收集异常-------");
                        bw.newLine();
                        bw.write("异常的名称:"+e.getCause().getClass().getSimpleName());
                        bw.newLine();
                        bw.write("异常的信息:"+e.getCause().getMessage());
                        bw.newLine();
                        bw.write("======异常收集完毕=======");
                        bw.newLine();
                        bw.newLine();
                        count++;

                    }
                }
            }
            try {
                bw.write("共有"+count+"个异常");
            }finally {
                if (bw != null){    //  关流
                    bw.close();
                }
            }
        }
    }
}
上一篇:ES(7) Request Body 和 Query DSL


下一篇:Spring的datasource配置详解【转】