黑马程序员_正则表达式和反射的学习

来源:互联网 发布:分割线知乎 编辑:程序博客网 时间:2024/05/17 02:55

-----------android培训java培训、java学习型技术博客、期待与您交流!----------

1.正则表达式
 (1)正则表达式就是符合一定规则的字符串。
 (2)掌握的规则:通过这些常见的规则,看懂别人写的正则表达式。
  A:字符
   x 字符x
   \\ 反斜线字符 
   \r 回车符
   \n 换行符
   
  B:字符类
   [abc] a、b 或 c
   [^abc] 任何字符,除了 a、b 或 c
   [a-zA-Z] a 到 z 或 A 到 Z,两头的字母包括在内 
   [0-9] 包含0-9的字符
   
  C:预定义字符类
   . 任何字符
   \d 数字:[0-9] 
   \w 单词字符:[a-zA-Z_0-9] 
   
  D:边界适配器
   ^ 行的开头
   $ 行的结尾 
   \b 单词边界
    这里不是单词 
    haha hehe xixi hello world 
    \b[a-z]{4}\b
    
  E:数量词
   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)正则表达式的功能:
  A:匹配功能
   String -- matches
  B:切割功能
   String -- split
  C:替换功能
   String -- replaceAll
  D:获取功能
   Pattern
   Matcher
    find()
    group()

[html] view plaincopy
  1. import java.util.Arrays;  
  2.   
  3. /*  
  4.  * "192.168.3.23 202.10.34.2 3.3.3.3 127.0.0.1 80.12.23.34"。  
  5.  * 能将这些ip地址排序。按照地址段数值从小到大排序。最后以一个字符串输出。  
  6.  * 思路:  
  7.  *      1:把每一位的前面都添加两个0。  
  8.  *      2:把每一位保留3位。  
  9.  *      3:切割得到一个字符串数组,对其进行排序即可。  
  10.  *      4:把排序后的字符串数组转成一个字符串  
  11.  */  
  12. public class IPDemo {  
  13.     public static void main(String[] args) {  
  14.         //把每一位的前面都添加两个0。  
  15.         String str = "192.168.3.23 202.10.34.2 3.3.3.3 127.0.0.1 80.12.23.34";  
  16.           
  17.         String s1 = str.replaceAll("(\\d+)", "00$1");  
  18.         //00192  
  19.         //003  
  20.         // System.out.println("s1:"+s1);  
  21.           
  22.         //00192.00168.003.023 00202.0010.0034.002 003.003.003.003 00127.000.000.001 0080.0012.0023.0034  
  23.         //把每一位保留3位。  
  24.         String s2 = s1.replaceAll("0*(\\d{3})", "$1");  
  25. //      System.out.println("s2:"+s2);  
  26.           
  27.         //切割得到一个字符串数组,对其进行排序即可。  
  28.         String[] strArray = s2.split(" ");  
  29.         Arrays.sort(strArray);//自然排序  
  30.           
  31.         //把排序后的字符串数组转成一个字符串  
  32.         StringBuilder sb = new StringBuilder();  
  33.         for(String s : strArray){  
  34.             //再次去0  
  35.             String ss = s.replaceAll("0*(\\d+)", "$1");  
  36.             sb.append(ss).append(" ");  
  37.         }  
  38.           
  39.         String result = sb.toString().trim();  
  40.         System.out.println("result:"+result);  
  41.     }  
  42. }  

2:反射(掌握)
 (1)在程序的运行时期,通过字节码文件对象去使用构造方法,成员方法,成员变量。
 (2)三种方式获取字节码文件对象(
  A:Object类的getClass()方法
  B:静态属性class
  C:Class类的静态方法forName(String className)
 (3)反射的使用

  在不同包下的类之间的相互调用是有限制的,特别是私有字段和方法,但是通过反射,我们可以获取。

  首先在不同包下建立了Person类


 

[html] view plaincopy
  1. /*  
  2.  * 要通过反射来使用Person类中的构造方法,成员方法,成员变量。  
  3.  */  
  4. public class Person {  
  5.     private String name;  
  6.     int age;  
  7.     public String address;  
  8.   
  9.     public Person() {  
  10.     }  
  11.       
  12.     Person(String name){  
  13.         this.name = name;  
  14.     }  
  15.   
  16.     public Person(String name, int age) {  
  17.         this.name = name;  
  18.         this.age = age;  
  19.     }  
  20.   
  21.     public void show() {  
  22.         System.out.println("show");  
  23.     }  
  24.   
  25.     public void haha(String str) {  
  26.         System.out.println("haha:" + str);  
  27.     }  
  28.   
  29.     public String hehe() {  
  30.         return "hehe";  
  31.     }  
  32.   
  33.     public String method(String name, int age) {  
  34.         return "method:" + name + ":" + age;  
  35.     }  
  36.   
  37.     private void function() {  
  38.         System.out.println("function");  
  39.     }  
  40.   
  41.     @Override  
  42.     public String toString() {  
  43.         return "name:" + name + ",age:" + age;  
  44.     }  
  45. }  


  A:获取构造方法并使用

[html] view plaincopy
  1. import java.lang.reflect.Constructor;  
  2.   
  3. import cn.itcast_02.Person;  
  4.   
  5. /*  
  6.  * 通过反射获取构造方法并使用  
  7.  */  
  8. public class ReflectDemo2 {  
  9.     public static void main(String[] args) throws Exception {  
  10.         // 获取字节码文件对象  
  11.         Class c = Class.forName("cn.itcast_02.Person");  
  12.   
  13.         // 获取带二个参数的构造方法  
  14.           
  15.         Constructor con = c.getConstructor(String.class, int.class);  
  16.   
  17.         // 创建对象  
  18.           
  19.         Object obj = con.newInstance("林青霞", 25);  
  20.         System.out.println(obj);  
  21.     }  
  22. }  


  B:获取成员变量并使用


 

[html] view plaincopy
  1. import java.lang.reflect.Constructor;  
  2. import java.lang.reflect.Field;  
  3.   
  4. /*  
  5.  * 通过反射获取成员变量并使用  
  6.  */  
  7. public class ReflectDemo {  
  8.     public static void main(String[] args) throws Exception {  
  9.         // 获取Class文件对象  
  10.         Class c = Class.forName("cn.itcast_02.Person");  
  11.   
  12.         // 获取所有的字段  
  13.         // public Field[] getFields() 所有公共字段  
  14.         // public Field[] getDeclaredFields() 所有字段  
  15.         // Field[] fields = c.getFields();  
  16.         Field[] fields = c.getDeclaredFields();  
  17.         for (Field field : fields) {  
  18.             System.out.println(field);  
  19.         }  
  20.   
  21.         System.out.println("***************************");  
  22.         // 使用无参构造方法创建了对象  
  23.         Constructor con = c.getConstructor();  
  24.         Object obj = con.newInstance();  
  25.         System.out.println(obj);// name:null,age:0  
  26.   
  27.         // 修改name的值  
  28.         // 获取name字段所对应的对象  
  29.         // public Field getField(String name)  
  30.         // public Field getDeclaredField(String name)  
  31.         // Exception in thread "main" java.lang.NoSuchFieldException: name  
  32.         Field field = c.getDeclaredField("name");  
  33.   
  34.           
  35.         //暴力访问  
  36.         field.setAccessible(true);  
  37.         field.set(obj, "林青霞"); // 给obj都系的field字段的值设置为林青霞  
  38.   
  39.         System.out.println(obj);// name:林青霞,age:0  
  40.     }  
  41. }  


  C:获取成员方法并使用

[html] view plaincopy
  1. import java.lang.reflect.Constructor;  
  2. import java.lang.reflect.Method;  
  3.   
  4. /*  
  5.  * 通过反射获取成员方法并使用。  
  6.  *   
  7.  *   
  8.  */  
  9. public class ReflectDemo {  
  10.     public static void main(String[] args) throws Exception {  
  11.         // 获取Class字节码文件对象  
  12.         Class c = Class.forName("cn.itcast_02.Person");  
  13.   
  14.         // 获取方法  
  15.         // public Method[] getMethods() 包括父类的公共的方法  
  16.         // public Method[] getDeclaredMethods() 本类的所有方法  
  17.         // Method[] methods = c.getMethods();  
  18.         Method[] methods = c.getDeclaredMethods();  
  19.         for (Method m : methods) {  
  20.             System.out.println(m);  
  21.         }  
  22.   
  23.         System.out.println("********************************");  
  24.         // 通过无参构造获取一个对象  
  25.         Constructor con = c.getConstructor();  
  26.         Object obj = con.newInstance();  
  27.   
  28.         // 获取单个方法并使用  
  29.         // public Method getMethod(String name,Class... parameterTypes)  
  30.         // 第一个参数name表示获取到的方法名  
  31.         // 第二个参数parameterTypes表示获取的方法的参数的Class类型参数  
  32.   
  33.         // 获取无参方法的对象  
  34.         Method m = c.getMethod("show");  
  35.         /*  
  36.          * Person p = new Person(); p.show();  
  37.          */  
  38.         // obj.m();  
  39.   
  40.         // public Object invoke(Object obj,Object... args)  
  41.         // 方法的返回值Object表示将来调用后的方法返回值  
  42.         // 第一个参数obj表示调用该方法的对象  
  43.         // 第二个参数args表示调用该方法的实际参数  
  44.         m.invoke(obj);  
  45.         System.out.println("********************************");  
  46.         // 调用带参数没有返回值的方法  
  47.         Method m2 = c.getMethod("haha", String.class);  
  48.         m2.invoke(obj, "林青霞");  
  49.         System.out.println("********************************");  
  50.         // 调用无参数有返回值的方法  
  51.         Method m3 = c.getMethod("hehe");  
  52.         Object objString = m3.invoke(obj);  
  53.         // String ss = (String)objString;  
  54.         System.out.println(objString);  
  55.         System.out.println("********************************");  
  56.         // 调用有参数有返回值的方法  
  57.         Method m4 = c.getMethod("method", String.class, int.class);  
  58.         Object objString2 = m4.invoke(obj, "王祖贤", 16);  
  59.         System.out.println(objString2);  
  60.         System.out.println("********************************");  
  61.         // 调用私有方法  
  62.         Method m5 = c.getDeclaredMethod("function");  
  63.         m5.setAccessible(true);  
  64.         m5.invoke(obj);  
  65.     }  
  66. }  


     反射可以避免编译期间的审查

[html] view plaincopy
  1. /*  
  2.  * 如果要在ArrayList<Integer>集合中添加一个字符串数据,如何实现呢?  
  3.  *   
  4.  * 通过反射可以避免泛型的编译期间检查。擦出泛型  
  5.  */  
  6. public class ArrayListTest {  
  7.     public static void main(String[] args) throws Exception {  
  8.         ArrayList<Integer> array = new ArrayList<Integer>();  
  9.   
  10.         // array.add("hello");  
  11.         // 使用反射解决  
  12.         Class c = array.getClass();  
  13.         Method m = c.getMethod("add", Object.class);  
  14.   
  15.         m.invoke(array, "hello");  
  16.         m.invoke(array, "world");  
  17.         m.invoke(array, "itcast");  
  18.   
  19.         System.out.println(array);  
  20.   
  21.         for (Integer i : array) {  
  22.             System.out.println(i);  
  23.         }  
  24.     }  
  25. }  


    学习感悟:"."在正则表达式中可以表示任意字符,如果用它作为正则来切割或者替换,必须加入转义字符,这里会犯错。反射可以逃过JAVA虚拟机的编译,这是因为泛型在编译之后将泛型擦掉了,所以字节码文件中是没有泛型信息的。


0 0