JAVA基础--正则与反射

正则表达式
1:正则表达式:符合某种规则的字符串(请注意正则表达式就是个字符串,只不过符合某种规则)

由一个案例引出了正则表达式
写一个程序要求:输入一个qq号,请判断输入的这个qq号是否正确?
  1)如果没有正则表达式的时候,写这个程序非常的麻烦

[java]  view plain  copy
  1. <span style="white-space:pre">            </span>private static boolean checkQq(String qq) {  
  2.                     boolean flag = true;  
  3.                     // 长度  
  4.                     if (qq.length() >= 5 && qq.length() <= 15) {  
  5.                         //是否不是0开头  
  6.                         if(!qq.startsWith("0")){  
  7.                             //判断全部是数字  
  8.                             char[] chs = qq.toCharArray();  
  9.                             for(char ch : chs){  
  10.                                 if(!(ch>='0' && ch<='9')){  
  11.                                     flag = false;  
  12.                                     break;  
  13.                                 }  
  14.                             }  
  15.                         }else{  
  16.                             flag = false;  
  17.                         }  
  18.                     } else {  
  19.                         flag = false;  
  20.                     }  
  21.                     return flag;  
  22.                 }  

   2)有了正则表达式非常的简单
[java]  view plain  copy
  1. private static boolean checkQq2(String qq) {  
  2.                     //return qq.matches("[1-9][0-9]{4,14}");  
  3.                     return qq.matches("[1-9]\\d{4,14}");  
  4.                 }  

2:正则表达式的规则:
A:字符
x 字符 x,任意字符代表自己本身。
\\ 反斜线字符 
\r 回车
\n 换行

B:字符类
[abc] a、b 或 c,任意字符一次。
[^abc] 任何字符,除了 a、b 或 c 
[a-zA-Z] a 到 z 或 A 到 Z,两头的字母包括在内
[0-9] 任意的数字字符一次

C:预定义字符类
. 任意的字符
\d 数字:[0-9] 
\w 单词字符:[a-zA-Z_0-9] 
单词字符:英文,数字,及_

D:边界匹配器
^ 行的开头 
$ 行的结尾 
\b 单词边界(也就是说这里出现的不能是单词字符)
abc hello world?haha

E:Greedy 数量词 
X? X,一次或一次也没有 
X* X,零次或多次 
X+ X,一次或多次 
X{n} X,恰好 n 次 
X{n,} X,至少 n 次 
X{n,m} X,至少 n 次,但是不超过 m 次 

F:组
捕获组可以通过从左到右计算其开括号来编号。组零始终代表整个表达式。
((A)(B(C))) 
第一组:(A)(B(C))
第二组:A
第三组:B(C)
第四组:C
3:正则表达式的应用
1)String类利用正则表达式完成字符串的判断功能(校验功能)(public boolean matches(String regex))
案例1:判断字符串”qaq”中间的字符是否是元音(aeiou)
String regex = "q[aeiou]q";
String str = "qbq";
boolean flag = str.matches(regex);
System.out.println(flag);
案例2:校验电话号码
String regex = "1[35]\\d{9}";
Scanner sc =new Scanner(System.in);
System.out.println("请输入你的手机号:");
String phone = sc.nextLine();
boolean flag = phone.matches(regex);
System.out.println(flag);
案例3:校验邮箱
//String regex = "[a-zA-Z_0-9]+@[a-zA-Z_0-9]{2,8}(\\.[a-zA-Z_0-9]{2,3})+";
String regex = "\\w+@\\w{2,8}(\\.\\w{2,3})+";
Scanner sc = new Scanner(System.in);
System.out.println("请输入你的邮箱:");
String email = sc.nextLine();
boolean flag = email.matches(regex);
System.out.println(flag);

2)String类利用正则表达式完成字符串的切割功能(public String[] split(String regex))
 
案例1:按 "." 来切割字符串"aa.bb.cc"
[java]  view plain  copy
  1. <span style="white-space:pre">            </span>String str2 = "aa.bb.cc";  
  2.                 String regex2 = "\\.";  
  3.                 String[] strArray2 = str2.split(regex2);  
  4.                 for (String s : strArray2) {  
  5.                     System.out.println(s);  
  6.                 }  

案例2:按 所有的空格 切割字符串"-1     99          4    23"
[java]  view plain  copy
  1. <span style="white-space:pre">                </span>String str4 = "-1  99    4 23";  
  2.                 String regex4 = " +";  
  3.                 String[] strArray4 = str4.split(regex4);  
  4.                 for (String s : strArray4) {  
  5.                     System.out.println(s);  
  6.                 }  
案例3:切割计算机上的路径,把每一层路径切割出来,
比如:D:\itcast\20131130\day27\code 切成 D:itcast 20131130 day27 code
[java]  view plain  copy
  1. <span style="white-space:pre">            </span>//注意java表示此路径要用这样的一个字符串:"D:\\itcast\\20131130\\day27\\code"  
  2.                 String str5 = "D:\\itcast\\20131130\\day27\\code";  
  3.                 String regex5 = "\\\\";  
  4.                 String[] strArray5 = str5.split(regex5);  
  5.                 for (String s : strArray5) {  
  6.                     System.out.println(s);  
  7.                 }  
案例4:按照叠词(重复字符)切割: "sdqqfgkkkhjppppkl";(这个地方引入了组的概念)
[java]  view plain  copy
  1. <span style="white-space:pre">            </span>String str = "sdqqfgkkkhjppppkl";  
  2.                 String regex = "(.)\\1+";  
  3.                 //".+" sdfgq  
  4.                 //"(.)\\1+"  ssss  
  5.                 //右边出现的应该是和左边是一模一样的。  
  6.                 String[] strArray = str.split(regex);  
  7.                 for (String s : strArray) {  
  8.                     // sd,fg,hj,kl  
  9.                     System.out.println(s);  
  10.                 }  
3)String类利用正则表达式完成字符串的替换功能
public String replaceAll(String regex,String replacement):用给定的字符串去替换字符串对象中满足正则表达式的字符。

案例1:把"sdaaafghccccjkqqqqql"替换成"sdafghcjkql",也就是叠词只留一个字符
[java]  view plain  copy
  1. <span style="white-space:pre">        </span>String str2 = "sdaaafghccccjkqqqqql";  
  2.                 // 叠词是在同一个字符串中用\编号来引用  
  3.                 String regex2 = "(.)\\1+";  
  4.                 // 在替换方法中,第二个字符串数据中可以使用$编号的形式来引用第一个正则表达式中的组的内容  
  5.                 String result2 = str2.replaceAll(regex2, "$1");  
  6.                 System.out.println(result2);  
  7.                 System.out.println("--------------------");  

案例2:把某个嘴很磕巴的人写出的一个字符串 
“我我....我...我.要...要要...要学....学学..学.编..编编.编.程.程.程..程” 还原成 “我要学编程”
[java]  view plain  copy
  1. <span style="white-space:pre">            </span>String str = "我我....我...我.要...要要...要学....学学..学.编..编编.编.程.程.程..程";  
  2.                 String result = str.replaceAll("\\.""");  
  3.                 String finalResult = result.replaceAll("(.)\\1+""$1");  
  4.                 System.out.println(finalResult);  

4)用正则表达式的包装类Pattern 和 匹配器Mathcher 结合 来完成 查找获取功能
①:记住获取模式对象和匹配器对象的这两步
// 把正则表达式编译成模式对象
Pattern p = Pattern.compile("a*b");
// 通过模式对象调用匹配方法获取到匹配器对象
Matcher m = p.matcher("aaaaab");
// 调动匹配器对象的判断功能

②:Mathcher的matches方法 和String类的matches方法差不多,只不过调用方式不一样
二者区别:
A:Mathcher的matches方法没有参数,因为在生成匹配器对象的这个过程中,
  就已经把正则表达式,和需要查找的字符串传给了匹配器对象

B:String类的matches方法
String对象直接调用public boolean matches(String regex)方法,把正则表达式传进来

// 把正则表达式编译成模式对象
Pattern p = Pattern.compile("a*b");
// 通过模式对象调用匹配方法获取到匹配器对象
Matcher m = p.matcher("aaaaab");
// 调动匹配器对象的判断功能
boolean b = m.matches();
System.out.println(b);

③:Mathcher的find()方法和group()方法
find():找到字符串中匹配正则表达式的字符 返回值类型是boolean 找到了就true 找不到就false
group():获取find()找到字符

案例1:想要获取字符串中 3个字符组成的单词
[java]  view plain  copy
  1. // 定义规则  
  2.                 String regex = "\\b[a-z]{3}\\b";  
  3.                 String str = "da jia zhu yi le, ming tian bu fang jia, xie xie!";  
  4.                 // 想要获取3个字符组成的单词  
  5.                 Pattern p = Pattern.compile(regex);  
  6.                 Matcher m = p.matcher(str);  
  7.                 while(m.find()){  
  8.                     System.out.println(m.group());  
  9.                 }  
案例2:请把mail.txt中所有邮箱找到,并遍历出来。
A:通过字符输入流读取数据。
B:把读取到的每一行数据进行查找。
C:把查找到的数据存储到集合中。
D:遍历集合。
[java]  view plain  copy
  1. <span style="white-space:pre">            </span>// 通过字符输入流读取数据。  
  2.                     BufferedReader br = new BufferedReader(new FileReader("mail.txt"));  
  3.                     // 创建一个集合  
  4.                     ArrayList<String> array = new ArrayList<String>();  
  5.   
  6.   
  7.                     // 定义邮箱规则  
  8.                     String regex = "\\w+@\\w{2,8}(\\.\\w{2,3})+";  
  9.   
  10.   
  11.                     String line = null;  
  12.                     while ((line = br.readLine()) != null) {  
  13.                         Pattern p = Pattern.compile(regex);  
  14.                         Matcher m = p.matcher(line);  
  15.                         while (m.find()) {  
  16.                             array.add(m.group());  
  17.                         }  
  18.                     }  
  19.   
  20.   
  21.                     // 遍历集合。  
  22.                     for (String s : array) {  
  23.                         System.out.println(s);  
  24.                     }  
  25.                     br.close();  

反射
1:反射机制:JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;
 对于任意一个对象,都能调用它的任意一个方法和属性,这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制

2:学习反射需要有以下步骤
A:首先学习字节码文件
B:第二学习 获取字节码文件的构造方法 并创建对象
C:有了对象了,就要学会获取对象中的成员变量
D:能获取对象中的成员变量了,那么还要学习成员方法

1)字节码文件的三种获取方式

①:Object类的getClass()方法:对象.getClass()
Person p = new Person();
Class c = p.getClass();
注意所有同一个类的字节码文件对象(实例)都是同一个(因为一个类就有唯一的字节码文件)
比如:  Person p = new Person();
Class c = p.getClass();


Person p2 = new Person();
Class c2 = p2.getClass();


System.out.println(p == p2);// false
System.out.println(c == c2);// true

②:数据类型的静态的class属性:类名.class
Class c3 = Person.class;

③:通过Class类的静态方法forName(String className)(一般只用最后一种,前面两种了解即可)
Class c4 = Class.forName("cn.itcast_01.Person");

2)反射获取类的构造方法
public Constructor<?>[] getConstructors():所有公共构造方法
public Constructor<?>[] getDeclaredConstructors():所有构造方法 包括私有
public Constructor<T> getConstructor(Class<?>... parameterTypes):获取单个构造方法
比如:
[java]  view plain  copy
  1. <span style="white-space:pre">                    </span>Class c = Class.forName("cn.itcast_01.Person");  
  2.                     Constructor con = c.getConstructor();//获取无参构造,因为没有参数  
  3.                     Object obj = con.newInstance();//用无参构造方法创建对象  
  4.                     System.out.println(obj);  
  5.   
  6.                     Constructor con = c.getConstructor(String.classint.class);//获取有参构造,因为有参数  
  7.                     Object obj = con.newInstance("林青霞"26);//用有参构造方法创建对象  
  8.                     System.out.println(obj);  
注意:
这个地方讲了一个可变参数
[java]  view plain  copy
  1.   <span style="white-space:pre">      </span> public static void main(String[] args) {  
  2.     int a = 10;  
  3.     int b = 20;  
  4.     int result = sum(a, b);//随意传任意个参数  
  5.     System.out.println(result);  
  6.   
  7.   
  8.     int c = 30;  
  9.     result = sum(a, b, c);//随意传任意个参数  
  10.     System.out.println(result);  
  11.   
  12.   
  13.     int d = 40;  
  14.     result = sum(a, b, c, d);//随意传任意个参数  
  15.     System.out.println(result);  
  16.   
  17.   
  18.     int e = 50;  
  19.     result = sum(a, b, c, d, e);//随意传任意个参数  
  20.     System.out.println(result);  
  21.   
  22.   
  23. }  
  24.   
  25.   
  26. public static int sum(int... x) {  
  27.     int result = 0;  
  28.     for (int i : x) {//底层就会把参数们封装层成一个数组,所以x是个数组  
  29.         result += i;  
  30.     }  
  31.     return result;  
  32. }  
3)反射获取类的成员变量
Field[] fields = c.getFields();// 获取所有公共的成员变量
Field[] fields = c.getDeclaredFields();// 获取所有的成员变量
Field field = c.getField("age");// 获取单个的成员变量
比如:获取非私有的单个成员变量
[java]  view plain  copy
  1. <span style="white-space:pre">                </span>// 获取字节码文件对象  
  2.                     Class c = Class.forName("cn.itcast_01.Person");  
  3.                     //获取构造器对象  
  4.                     Constructor con = c.getConstructor();  
  5.                     Object obj = con.newInstance();  
  6.                     // 获取单个的成员变量  
  7.                     Field field = c.getField("age");  
  8.                     field.set(obj, 20);//给obj对象的field字段赋值为20  
  9.                     System.out.println(obj);  
  10.   
  11.   
  12.                      获取私有的单个成员变量  
  13.                     // 获取字节码文件对象  
  14.                     Class c = Class.forName("cn.itcast_01.Person");  
  15.                     // 创建对象  
  16.                     Constructor con = c.getConstructor();  
  17.                     Object obj = con.newInstance();  
  18.                     Field nameField = c.getDeclaredField("name");  
  19.                     nameField.setAccessible(true);//你就不要限制我了。这个地方是暴力访问,是Field父类的方法  
  20.                     nameField.set(obj, "林青霞");  
4)反射获取类的成员方法
[java]  view plain  copy
  1. <span style="white-space:pre">        </span>Method[] methods = c.getMethods();// 所有公共方法,包括父类的  
  2.             Method[] methods = c.getDeclaredMethods();// 本类的所有方法  
  3.               
  4.             Method m1 = c.getMethod("show"null);//无参数无返回值  
  5.             m1.invoke(obj, null);  
  6.   
  7.   
  8.             Method m2 = c.getMethod("function", String.class);//带参数无返回值  
  9.             m2.invoke(obj, "林青霞");  
  10.   
  11.   
  12.             Method m3 = c.getMethod("reutrnValue", String.class,int.class);//带多个参数有返回值   
  13.             Object ooo = m3.invoke(obj, "林青霞",26);// ooo就是返回的值  
  14.   
  15.   
  16.             Method m4 = c.getDeclaredMethod("hello"null);//私有方法的调用  
  17.             m4.setAccessible(true);//暴力访问  
  18.             m4.invoke(obj, null);  
3:案例:动态创建某个配置文件中提供的一个类的名字的这个类的对象,并执行其方法
[java]  view plain  copy
  1. <span style="white-space:pre">        </span>Properties prop = new Properties();  
  2.         FileReader fr = new FileReader("test.properties");  
  3.         prop.load(fr);  
  4.         fr.close();  
  5.           
  6.         //获取类名  
  7.         String className = prop.getProperty("className");  
  8.         //获取方法名  
  9.         String methodName = prop.getProperty("methodName");  
  10.           
  11.         //获取字节码文件对象  
  12.         Class c = Class.forName(className);  
  13.       
  14.         Constructor con = c.getConstructor();  
  15.         Object obj = con.newInstance();  
  16.           
  17.         Method m = c.getMethod(methodName, null);  
  18.         m.invoke(obj, null);  

4:泛型只是在编译期间(或者是你在写代码期间)强制要求你的做的一些规范,
等编译通过生成了字节码文件后,泛型就会被擦除,运行期间就没有泛型了
[java]  view plain  copy
  1. ArrayList<Integer> array = new ArrayList<Integer>();  
  2.         // 获取字节码文件对象  
  3.         Class c = array.getClass();  
  4.         Method m = c.getMethod("add", Object.class);  
  5.         m.invoke(array, "hello");  
  6.         m.invoke(array, "world");  
  7.         m.invoke(array, "java");  
  8.         System.out.println(array);  
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值