Java基础26 注解 正则表达式

一、注解概念

1.注释:用于对代码的进行解释 主要是给程序员看的
2.注解:用于对代码进行说明 主要是用于JVM(计算机)看

3.定义:
注解(Annotation),也叫元数据,一种代码级别的说明,本质是一个接口。它是jdk1.5及以后版本引入的一个特性,与类、接口、枚举 是同一个层次。
它可以声名在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释
A.在jdk1.5之后才能使用 B.用来对这些元素进行说明,注释
4.作用分类
编写文档:通过代码里标识的注解生成文档 生成文档doc文档
代码编写:通过代码里标识的注解对代码进行分析 使用反射
编译检查:通过代码里表示的注解让编译器能够实现基本的编译检查 @Override @FunctionInterface

jdk提供的注解

1.@Override 它的作用是标记子类是否是重写父类的方法
2.@Deprecated 用于标识已经过时的方法 但是还是可以使用 例如线程的stop()方法
3.@SuppressWarnings 用于压制去除黄色警告,黄色警告是命名不规范
SuppressWarnings ( “all”)参数是all 表示去除所有警告
可以标注在方法上 也可以标注在类上 可以标注属性
4.代码

package day26;
@SuppressWarnings(value = "all")
public class Test01 {
    @Override
    public String toString() {
        return super.toString();
    }
    @Deprecated
    public void show1(){
        //这个方法已经过时 不推荐使用
    }
    public void show2(){

    }
    public void show3(){

    }
    public void mm(){
        System.out.println("哈哈哈");
    }

}

自定义的注解

1.元注解格式
public @interface 注解的名称 {}
2.注解本质:其实是一个接口
3.属性:表示接口中所有的成员 静态常量(不关注) 抽象方法(关注)注解的属性就是接口的抽象方法,只是在注解里被称为属性
属性的返回值类型
1.基本数据类型 四类八种
2.字符串类型
3.枚举类型
4.注解类型
5.以上类型的数组

代码
public @interface MyAnno{}
等同于public interface MyAnno extends java.lang.annotation.Annotation{}
所以注解本质是接口

package day26;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnno {
    //public interface MyAnno extends java.lang.annotation.Annotation{}
    //返回值为基本类型
    int getnum();
    //返回值为String类型
    String getStr();
    //返回值为枚举类型
    Color show01();
    //返回值为注解类型
    My show02();
   //返回值为以上类型的数组
    String [] getshowInfo();
    //设置默认属性值
    String getStr() default "张三";
    

}

package com.qf.demo13;
/*@MyAnno(getnum=18,getStr="张三")*/
/*@MyAnno(getnum=18)*/
/*@MyAnno(getshowInfo= {"ddd","aaaa","bbb"})*/
@MyAnno(getStr = "aaa")
public class Test01 {
}

属性赋值
1.使用注解的时候 必须给所有的属性进行赋值
2.如果使用注解的时候 不想给其赋值 必须设置默认值 default 来设置默认值
3.如果是给注解的中属性的数组进行赋值 多个值可以使用大括号 一个值可以省略大括号
4.如果属性值只有一个且属性名为value 可以不写属性名 直接进行赋值 例SuppressWarnings(value=“all”) 简写为SuppressWarnings(“all”)

元注解

1.用于来描述注解的注解就称为是元注解
2.常用的元注解四个
@Target 主要用于来表示注解作用的位置
ElementType.TYPE 表示注解可以在类上使用
ElementType.FIELD 表示注解在属性上使用
ElementType.METHOD 表示注解可以在方法使用
@Retention 主要用于注解是否可以被识别
RetentionPolicy.RUNTIME ==>在运行期间 生成对应的class文件 并且jvm 可以识别这个注解 开发的大部分场景都是使用这个

@Documented 用于标注是否在api文档上 显示这个注解
@Inherited 用于表示注解是否继续被子类继承的使用

使用注解 实现反射案例

step01 需求 在不更改代码的前提 调用任意类的任意的方法
step02 代码
注解类

package day26;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnno {
    String name();
    int age();

}

实体类

package day26;

public class Student {
    public void show(){
        System.out.println("你好");
    }
}

测试类
先获取当前类的类对象,即Class cla = Test02.class;
通过当前类对象获取当前类的注解类对象,ProAnno proAnno = (ProAnno) cla.getAnnotation(ProAnno.class);
得到注解类对象就能得到注解的属性值

package day26;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

@ProAnno(className = "day26.Student",methodName = "show")
public class Test02 {
    public static void main(String[] args) {
        //获取当前类的对象
        Class<Test02> cla = Test02.class;
        //获取注解的对象
        //不能省略强转
        ProAnno proAnno = (ProAnno) cla.getAnnotation(ProAnno.class);
        //获取包名的名称
        String className = proAnno.className();
        //获取方法的名称
        String methodName =proAnno.methodName();
        System.out.println(className);
        System.out.println(methodName);
        //获取这个类Class对象
        try {
            Class<?> c = Class.forName(className);
            Constructor<?> con = c.getConstructor();
            Object obj = con.newInstance();
            Method m = c.getMethod(methodName);
            m.invoke(obj);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }


    }
}

案例1

step01需求:使用注解来做一个简单的测试的工具类
step02:分析

1.定义一个注解类 需要加上元注解
2.在检测的方法中使用这个注解
3.通过反射获取当前类中所有的方法 验证带注解的方法
如果带注解的方法 出现的了异常 把异常信息写入到文件
如果不出现异常正确在控制台进行打印
注解类

package day26;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnno1 {

}

工具类

package day26;
/**
 * 检查井工具类中是否有异常 有异常需要把异常收集 写入
 * 并需要显示异常出现的出现
 */
public class PayUtils {
    @MyAnno1
    public void show1(){
        String str =null;
        str.toString();
        System.out.println("a+b="+(1+0));
    }
    @MyAnno1
    public void show2(){
        System.out.println("a-b="+(1-0));
    }
    @MyAnno1
    public void show3(){
        System.out.println("a*b="+(1*0));
    }
    @MyAnno1
    public void show4(){
        System.out.println("a/b="+(1/0));
    }
    @MyAnno1
    public void show5(){
        System.out.println("没有bug代码");
    }
}

测试类

package day26;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Test03 {
    public static void main(String[] args) throws IOException {
        //定义一个写的流
        BufferedWriter bw =new BufferedWriter(new FileWriter("bug.txt"));
        //获取工具类 实例化对象
        PayUtils pay =new PayUtils();
        //获取 当前类的字节码文件
        Class  cla= pay.getClass();
        //获取class对象中所有的方法
        Method[] methods = cla.getMethods();
        //定义一个变量来记录其次数
        Integer count=0;
        //对方法进行遍历
        for (Method m : methods) {
            //方法上是否有这个注解
            //如果为true 表示加上了这个注解 否则就没有
            if(m.isAnnotationPresent(MyAnno1.class)){
                //调用方法
                try {
                    m.invoke(pay);
                } catch (Exception e) {
                    bw.write(m.getName()+"出现了bug");
                    bw.newLine();
                    bw.write("处理的异常是:"+e.getCause().getClass().getSimpleName());
                    bw.newLine();
                    bw.write("异常的信息"+e.getCause().getMessage());
                    bw.newLine();
                    bw.write("-----------------");
                    bw.newLine();
                    count++;
                }
            }
        }
        bw.write("共出现bug"+count+"次");
        bw.flush();
        bw.close();
    }
}

案例2

step01 使用注解给学生的属性name 与age 进行赋值 并且获取
step02 分析
1.定义一个注解类
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
2.定义两个方法(属性)
第一个方法用于来设置名称
第二个方法就是用于来设置年龄
3.在执行程序的时候 需要加上这个注解 进行赋值 最后才能取值
注解类

package day26;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnno {
    String name();
    int age();

}

测试类
需要在测试类上加注解 @MyAnno(name = “liu”,age = 18)

package day26;

import java.lang.annotation.Annotation;

@MyAnno(name = "liu",age = 18)
public class Test04 {
    public static void main(String[] args) {
        Class cla = Test04.class;
        MyAnno myAnno = (MyAnno) cla.getAnnotation(MyAnno.class);
        System.out.println(myAnno.name());
        System.out.println(myAnno.age());
    }
}

正则表达式

1.正则表达式其实就是一个特殊的字符串 每一个字符都有其特殊的含义
2.作用: 一般用于前后端来做验证(登录 注册的 表单提交的)
3.好处:
可以使用比较简单的代码 来表示复杂的逻辑
坏处:
写不对
规则比较难记
4.需求 验证一个qq好是否合法
长度必须是5-15
每一个字符都必须是数组
第一个字符不能是0
5.代码

public class Test {
public static void main(String[] args) {
// System.out.println(isFlag("1234567890000444444"));
// System.out.println(isFlag("123456789"));
System.out.println(isFlag("12345678a9"));
// System.out.println(isFlag("023456"));
String reg="[1-9]\\d{4,14}";
System.out.println(reg.matches("12345678a9"));
}
public static boolean isFlag(String s){
boolean flag = true;
//判断正确的情况
if(s.length() >=5 && s.length() <=15){
if(!s.startsWith("0")){
//需要将字符串转换为字符的数组
char [] ch = s.toCharArray();
for (Character c: ch){
if(c >= '0' && c <='9'){
//正确
flag = true;
}else {
//不确定
flag = false;
break;
}
}
}else{
flag = false;
}
}else {
flag = false;
}
return flag;
}
}

正则的规则-字符类

[abc] a、b 或 c(简单类)
[ ^abc] 任何字符,除了 a、b 或 c(否定)
[a-zA-Z] a 到 z 或 A 到 Z,两头的字母包括在内(范围)
[a-d[m-p]] a 到 d 或 m 到 p:[a-dm-p](并集)
[a-z&&[def]] d、e 或 f(交集)
[a-z&&[ ^bc]] a 到 z,除了 b 和 c:[ad-z](减去)
[a-z&&[ ^m-p]] a 到 z,而非 m 到 p:[a-lq-z](减去)

正则的规则-预定义字符类

. 任何字符(与行结束符可能匹配也可能不匹配)
\d 数字:[0-9]
\D 非数字: [ ^0-9]
\s 空白字符:[ \t\n\x0B\f\r]
\S 非空白字符:[ ^\s]
\w 单词字符:[a-zA-Z_0-9]
\W 非单词字符:[ ^\w]

public void show2(){
//规则
String reg = "\\d";
System.out.println("%".matches(reg));
System.out.println("w".matches(reg));
System.out.println("q".matches(reg));
System.out.println("a".matches(reg));
System.out.println("1".matches(reg));
System.out.println("".matches(reg));
System.out.println(" ".matches(reg));
}

正则规则-Greedy 数量词

X? X只出现一次
X* X出现0次或者是多次 空串""
X+ X一次或多次
X{n} X恰好 n 次
X{n,} X至少 n 次
X{n,m} X至少 n 次,但是不超过 m 次

public void show1(){
String reg = "[abc]?";
System.out.println("a".matches(reg));
System.out.println("b".matches(reg));
System.out.println("ab".matches(reg));
System.out.println("ad".matches(reg));
}
public void show2(){
String reg = "[abc]*";
System.out.println("a".matches(reg));
System.out.println("d".matches(reg));
System.out.println("ab".matches(reg)); //多次
}
public void show4(){
String reg = "[abc]{4}";
System.out.println("abca".matches(reg));
System.out.println("d".matches(reg));
System.out.println("ab".matches(reg)); //多次
System.out.println("ad".matches(reg));
}
public void show5(){
String reg = "[abc]{4,}";
System.out.println("abca".matches(reg));
System.out.println("bbbb".matches(reg));
System.out.println("abcaaaaa".matches(reg));
System.out.println("abcaaaaabbbbbbb".matches(reg));
System.out.println("ab".matches(reg)); //多次
}
public void show6(){
String reg = "[abc]{4,15}";
System.out.println("abcaaaaaabcabca".matches(reg));
System.out.println("abcaaaaabbbbbbbaaaaaaaaa".matches(reg));
System.out.println("b".matches(reg));
System.out.println("ab".matches(reg)); //多次
}

案例3

step 01 需求: 身份证验证的正则
step02 分析:
只是对身份证的位置 以及首字符来进行验证
String reg =“[1-9]\d{14}|[1-9]\d{17}”

public class Test04 {
public static void main(String[] args) {
String reg ="[1-9]\\d{14}|[1-9]\\d{17}";
System.out.println("0123456792345666".matches(reg));
System.out.println("3333333323456792345666".matches(reg));
System.out.println("456792345666234568".matches(reg));
}
}

正则参考 word文档 以及 在线正则网站 https://tool.oschina.net/regex#
正则中常使用三个方法
在这里插入图片描述

public class Test {
public static void main(String[] args) {
String s = "中国.你好.我为骄傲";
String [] arrays = s.split("\\.");
System.out.println(Arrays.toString(arrays));
}
}
public class Test01 {
public static void main(String[] args) {
String s="andbbccdd47474747jh和订货会3333金凤凰";
String s1 = s.replaceAll("\\d","");
System.out.println(s1);
}
}

案例4

step01 需求 定义一个字符串 String str=“30 90 40 50 79 20”; 需要将这字符串的每一个元素 转换为int
类型
存入到int类型数组 对数组中的元素进行排序 ==》 打印出来
step02 分析
1.需要将字符串按照空格进行分割 " " ==>字符串类型的数组
2.遍历数组 将每一个元素转换int类 存入到数组
3.数组工具类的方法
4.打印
step03代码

public class Test02 {
public static void main(String[] args) {
//定义一个字符串
String str = "20 100 39 70 63 377";
//根据空格来进行分割
String [] arrays = str.split(" ");
//初始化一个Integer数组
Integer[] nums = new Integer[arrays.length];
for (int i=0;i<arrays.length;i++){
nums[i] = Integer.parseInt(arrays[i]);
}
//进行排序
Arrays.sort(nums);
//进行打印输出
System.out.println(Arrays.toString(nums));
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值