反射与正则表达式

三、反射 

在一些通用的框架中,很多情况下,我们并不知道程序的源码,所能拿到的往往是一些class文件,

在这种情况下,如果想要知道源程序的构造,反射,可以帮我们实现。

1、原理理解:

能够知道任意一个类的所有属性和方法,且能调用它的任意一个方法和属性,

这种动态获取的信息以及动态调用对象的方法的功能称为java语音的反射机制。

要解剖一个类,首先要获取到类的每一个字节码文件对应的Class类型的对象,

其中用的是Class类中的方法:

1)类名.class.
2)对象.class
3)Class.forName("类名")


2、获取class文件对象的方式:

三种方式:

1.

Person  p  =  new Person();

Class  c1  =  p.getClass();


2.

Class  c2  =  Person.class; 


3.

Class  c3  =  Class.forName(“myReflect.Person”);

PS:

c1  ==  c2   true

c2  ==  c3   true

1和2都运用于日常(2较方便),3常用于项目开发,

3中的全路径通常通过配置文件中存储的路径,因为容易出错。



    3、Constructor

    获取构造方法:

       1)得到这个类的所有构造方法:如得到上面示例中Person类的所有构造方法

            Constructor[] cons = Class.forName(“myReflect.Person”).getConstructors();

      2)获取某一个构造方法:

           Constructor con=Person.class.getConstructor(String.class,int.class);

括号中是参数的字节码文件对象。

4、Field

获取类中一个成员变量

       FieldgetField(String s);//只能获取公有和父类中公有

     FieldgetDeclaredField(String s);//获取该类中任意成员变量,包括私有

     setAccessible(ture);

     //如果是私有字段,要先将该私有字段进行取消权限检查的能力。也称暴力访问。

  set(Objectobj, Object value);//将指定对象变量上此Field对象表示的字段设置为指定的新值。

     Object get(Objectobj);//返回指定对象上Field表示的字段的值。


5、Method

调用某个对象身上的方法,要先得到方法,再针对某个对象调用。

       Method[] getMethods();//只获取公共和父类中的方法。

        Method[] getDeclaredMethods();//获取本类中包含私有。

        Method  getMethod("方法名",参数.class(如果是空参可以写null));

        Object invoke(Objectobj ,参数);//调用方法

       如果方法是静态,invoke方法中的对象参数可以为null。

示例1:
[java] view plaincopy
  1. import java.lang.reflect.Constructor;    
  2. import java.lang.reflect.Field;    
  3.     
  4. public class ReflectField {    
  5.     public static void main(String[] args) {    
  6.         Class clazz = Human.class;// 获取字节码文件对象    
  7.     
  8.         // 获取所有的成员变量    
  9.         // Field[] fields = c.getFields();    
  10.         Field[] fields = clazz.getDeclaredFields();    
  11.         for (Field field : fields) {    
  12.             System.out.println(field);    
  13.             /*输出:   
  14.              * private java.lang.String Human.name   
  15.              * private int Human.age  
  16.              * private java.lang.String Human.address  
  17.              */    
  18.         }    
  19.     
  20.         // 获取单个的成员变量并赋值    
  21.         try {    
  22.             // 通过带参构造方法创建对象    
  23.             Constructor con = clazz.getConstructor(String.classint.class,    
  24.                     String.class);// 这个是公共构造方法    
  25.             Object obj = con.newInstance("天下第一"22"中国·武汉");    
  26.     
  27.             // 获取address并对其赋值    
  28.             // Field addressField = clazz.getField("address");//NoSuchFieldException    
  29.             Field addressField = clazz.getDeclaredField("address");    
  30.             // public void set(Object obj,Object value)    
  31.             // 将指定对象变量上此 Field 对象表示的字段设置为指定的新值。    
  32.             addressField.setAccessible(true);// 因为IllegalAccessException,所有要暴力访问    
  33.             addressField.set(obj, "武汉"); // 给obj对象的addressField字段设置值为"武汉"    
  34.     
  35.             // 获取name并对其赋值    
  36.             Field nameField = clazz.getDeclaredField("name");    
  37.             nameField.setAccessible(true);// 因为IllegalAccessException,所有要暴力访问    
  38.             nameField.set(obj, "night");    
  39.     
  40.             // 获取age并对其赋值    
  41.             Field ageField = clazz.getDeclaredField("age");    
  42.             ageField.setAccessible(true);    
  43.             ageField.set(obj, 22);    
  44.     
  45.             ((Human) obj).show();// :22——武汉   
  46.     
  47.         } catch (Exception e) {    
  48.             e.printStackTrace();    
  49.         }    
  50.     }    
  51.     
  52. }    
  53. class Human {    
  54.     private String name;    
  55.     private int age = 0;    
  56.     private String address = "未填写";    
  57.     
  58.     private Human(String name) {    
  59.         this.name = name;    
  60.     }    
  61.     
  62.     public Human(String name, int age, String address) {    
  63.         this.name = name;    
  64.         this.age = age;    
  65.         this.address = address;    
  66.     }    
  67.     
  68.     public void show() {    
  69.         System.out.println(name + ":" + age + "——" + address);    
  70.     }    
  71. }    

四、正则表达式

正则即是正确的规则。

正则表达式通过一些特殊的符号来操作字符串数据,可以简化书写,不过定义太多也不便于阅读。

字符
x字符 x
\\反斜线字符
\0n带有八进制值 0 的字符 n (0 <= n <= 7)
\0nn带有八进制值 0 的字符 nn (0 <= n <= 7)
\0mnn带有八进制值 0 的字符 mnn(0 <= m <= 3、0 <= n <= 7)
\xhh带有十六进制值 0x 的字符 hh
\uhhhh带有十六进制值 0x 的字符 hhhh
\t制表符 ('\u0009')
\n新行(换行)符 ('\u000A')
\r回车符 ('\u000D')
\f换页符 ('\u000C')
\a报警 (bell) 符 ('\u0007')
\e转义符 ('\u001B')
\cx对应于 x 的控制符

字符类
[abc]ab 或 c(简单类)
[^abc]任何字符,除了 ab 或c(否定)
[a-zA-Z]a 到 z 或 A 到 Z,两头的字母包括在内(范围)
[a-d[m-p]]a 到 d 或 m 到 p[a-dm-p](并集)
[a-z&&[def]]de 或 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]

POSIX 字符类(仅 US-ASCII)
\p{Lower}小写字母字符:[a-z]
\p{Upper}大写字母字符:[A-Z]
\p{ASCII}所有 ASCII:[\x00-\x7F]
\p{Alpha}字母字符:[\p{Lower}\p{Upper}]
\p{Digit}十进制数字:[0-9]
\p{Alnum}字母数字字符:[\p{Alpha}\p{Digit}]
\p{Punct}标点符号:!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~


五、正则表达式的常见操作:

1,匹配:其实用的就是String类中的matches方法。 
String reg = “[1-9][0-9]{4,14}”; 
boolean b = qq.matches(reg);//将正则和字符串关联对字符串进行匹配。 
2,切割:其实用的就是String类中的split方法。 
3,替换:其实用的就是String类中的replaceAll(); 
4,获取: 
1),先要将正则表达式编译成正则对象。使用的是Pattern中静态方法 compile(regex); 
2),通过Pattern对象获取Matcher对象。 
Pattern用于描述正则表达式,可以对正则表达式进行解析。 
而将规则操作字符串,需要从新封装到匹配器对象Matcher中。 
然后使用Matcher对象的方法来操作字符串。 
如何获取匹配器对象呢? 
通过Pattern对象中的matcher方法。该方法可以正则规则和字符串想关联。并返回匹配器对象。 
3),使用Matcher对象中的方法即可对字符串进行各种正则操作。

5、组和捕获

       捕获组可以通过从左到右计算其开括号来编号。例如,在表达式 ((A)(B(C)))中,存在四个这样的组:

                    1     ((A)(B(C)))

                    2     \A

                    3     (B(C))

                    4     (C)

       组零始终代表整个表达式。在替换中常用$匹配组的内容。

示例:
[java] view plaincopy
  1. import java.util.regex.*;    
  2.   
  3. public class Regex      
  4. {    
  5.     public static void sop(Object obj)    
  6.     {    
  7.         System.out.println(obj);    
  8.     }    
  9.     public static void main(String[] args)     
  10.     {    
  11.         functionDemo_1();    
  12.         sop("---------------------------");    
  13.         functionDemo_2();    
  14.         sop("---------------------------");    
  15.         functionDemo_3();    
  16.         sop("---------------------------");    
  17.         functionDemo_4();    
  18.         sop("---------------------------");    
  19.         functionDemo_5();    
  20.         sop("---------------------------");    
  21.         functionDemo_6();    
  22.         sop("---------------------------");    
  23.     }    
  24.     
  25.     public static void functionDemo_1()    
  26.     {    
  27.         //匹配手机号码    
  28.         String tel = "15072472927";    
  29.         String regex = "1[358]\\d{9}";    
  30.     
  31.         Boolean b = tel.matches(regex);    
  32.         sop(tel+":"+b);    
  33.     }    
  34.     public static void functionDemo_2()    
  35.     {    
  36.         //演示切割     
  37.         String tel = "zhangsan   lisi             wangwu";    
  38.         String[] gex = tel.split("\\s+");    
  39.     
  40.         for(String str : gex)    
  41.         {    
  42.             sop(str);    
  43.         }    
  44.     }    
  45.     public static void functionDemo_3()    
  46.     {    
  47.         //演示切割     
  48.         //(.)表示一组,\\1+表示与第1组相同的出现1次以上    
  49.         String tel = "zhangsanttttttlisimmmmmmmmmmmwangwu";    
  50.         String[] gex = tel.split("(.)\\1+");    
  51.     
  52.         for(String str : gex)    
  53.         {    
  54.             sop(str);    
  55.         }    
  56.             
  57.     }    
  58.     /*  
  59.      * 演示替换  
  60.      */    
  61.     public static void functionDemo_4()    
  62.     {    
  63.         //$表示前一个参数的第一组    
  64.         String tel = "zhangsanttliswangwu";    
  65.         String gex = tel.replaceAll("(.)\\1+","$1");    
  66.     
  67.             sop(gex);    
  68.             
  69.             
  70.     }    
  71.     public static void functionDemo_5()    
  72.     {    
  73.              
  74.         String tel = "15072472927";    
  75.         tel = tel.replaceAll("(\\d{3})(\\d{4})(\\d{4})","$1****$3");    
  76.     
  77.             sop(tel);    
  78.             
  79.             
  80.     }    
  81.      /*  
  82.      * 演示获取  
  83.      * 将正则规则进行对象的封装。  
  84.      * Pattern p = Pattern.compile("a*b");  
  85.      * 通过正则对象的matcher方法字符串相关联。获取要对字符串操作的匹配器对象Matcher。  
  86.      * boolean b = m.matches();  
  87.      */    
  88.     public static void functionDemo_6()    
  89.     {    
  90.          //打印三个字符的单词    
  91.          // \\b表示单词边界    
  92.         String tel = "da jia hao,ming tian bu fang jia";    
  93.             
  94.         //1. 将正则封装成对象    
  95.         String regex = "\\b[a-z]{3}\\b";    
  96.         Pattern p = Pattern.compile(regex);    
  97.             
  98.         //2. 通过正则对象获取匹配器对象    
  99.         Matcher m = p.matcher(tel);    
  100.     
  101.         //使用Matcher对象的方法对字符串进行操作。    
  102.         //既然要获取三个字母组成的单词。    
  103.         //查找:find();    
  104.         while (m.find())    
  105.         {    
  106.             sop(m.group());//获取匹配的子序列    
  107.             sop(m.start()+":"+m.end());//字符在字符串中的索引位置    
  108.         }    
  109.             
  110.             
  111.     }    
  112. }  
程序运行结果为:
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值