黑马程序员——反射与正则表达式

-------  android培训 java培训 、期待与您交流! ----------

一、类的加载:

原理理解:

当使用某个类的时候,如果该类还没有被加载到内存中,则系统会通过加载,连接,初始化三步来实现对这个类进行初始化。

a、加载:

就是指将class文件读入到内存,并创建一个Class对象

         任何类被使用时系统都会建立一个Class对象

b、连接:

         验证 : 是否有正确的内部结果,并和其他类协调一致。

         准备: 负责为类的静态成员分配内存,并配置默认初始化值。

        解析: 将类的二进制数据中的符号引用替换为直接的引用。

c、初始化 :

类初始化时机:

1.访问类的实例

2.访问类的静态变量,或者为静态变量赋值,

3.调用类的静态方法

4.调用反射方式来强制创建某个类或者接口对应的

5. Java.lang.Class对象。

6. 初始化某个类的子类

7. 直接使用java.exe命令来运行某个主类。

二、类加载器:

将.class文件加载到内存中,并生成对应的Class对象

分为三种:

1.BootstrapClassLoader 根类加载器:

(引导类加载器)负责java核心类加载,

如System,String等,在JDK中JRE的lib目录下rt.jar文件中

2.Extension ClassLoader扩展类加载器:

 负责JRE的扩展目录中Jar包的加载

在JDK中JRE的lib目录下ext目录

3.SystemClassLoader  系统类加载器:

负责在JVM启动时加载来自java命令的class文件

以及classpath环境变量所指定的jar包和类路径


三、反射 

1、原理理解:

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

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

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

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

成员变量 Field

构造方法 Constructor

成员方法  Method


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 plain copy
  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 plain copy
  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 = "zhangsanttttttlisimmmmmmmmmmmwangwu";    
  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. }  
程序运行结果为:


*另一个示例:网络爬虫
[java]  view plain copy
  1. /**  
  2.  * @author LinP  
  3.  *  网络爬虫  
  4.  * 网页爬虫:其实就是一个程序用于在互联网中获取符合指定规则的数据。  
  5.  * 爬取需要获取的信息。  
  6.  */    
  7. public class RegexDemo {    
  8.     
  9.     /**  
  10.      * @param args  
  11.      * @throws IOException   
  12.      */    
  13.     public static void main(String[] args) throws IOException {    
  14.         // TODO 自动生成的方法存根    
  15.         //getMailAddress();    
  16.         getMailAddressByWeb();    
  17.     }    
  18.         
  19.     private static void getMailAddressByWeb() throws IOException {    
  20.         // TODO 自动生成的方法存根    
  21.         URL url = new URL("http://bbs.itheima.com/thread-200600-1-1.html");    
  22.             
  23.         BufferedReader bufr = new BufferedReader(new InputStreamReader    
  24.                 (url.openStream()));    
  25.         Pattern p = Pattern.compile("\\w+(\\.\\w+)+");    
  26.             
  27.         String line = null;    
  28.         while((line = bufr.readLine())!=null){    
  29.             Matcher m = p.matcher(line);    
  30.             while(m.find()){    
  31.     
  32.                 System.out.println(m.group());    
  33.             }    
  34.         }    
  35.     
  36.     }    
  37.     
  38.     private static void getMailAddress() throws IOException {    
  39.         //1. 读取源文件。    
  40.         BufferedReader bufr = new BufferedReader(new FileReader    
  41.                 ("C:/Users/LinP/Desktop/gaoxin/3-反射/3-反射.html"));    
  42.             
  43.         //2. 对读取的数据进行规则的匹配。从中获取符合规则的数据。    
  44.         Pattern p = Pattern.compile("\\b\\.[a-zA-Z]{6}\\b");    
  45.             
  46.         ArrayList<String> list = new ArrayList<String>();    
  47.             
  48.         String line = null;    
  49.         while((line = bufr.readLine())!=null){    
  50.             Matcher m = p.matcher(line);    
  51.             while(m.find()){    
  52.                 System.out.println(m.group());    
  53.             }    
  54.         }           
  55.     }    
  56. }    
程序运行结果为:
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值