黑马程序员--java--反射和正则表达式

来源:互联网 发布:mac文件备份到移动硬盘 编辑:程序博客网 时间:2024/05/16 05:45


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

                       正则表达式

正则表达式:使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。

 特点

     1、正则表达式用于操作字符串数据。
     2、通过一些特定的符号来体现的。
     3、虽然简化了,但是阅读性差。

所以我们为了掌握正则表达式,必须要学习一些符号。
常见符号


 




四种具体功能

1、匹配:String类中的matches方法。

应用事例

 /* * 演示匹配。 */public static void functionDemo_1(){//匹配手机号码是否正确。 String tel = "15800001111";String regex = "1[358]\\d{9}";   boolean b = tel.matches(regex);System.out.println(tel+":"+b);}

2、切割:String类中的split方法。
应用事例
        /* * 切割。 *  * 把字符串用重复字母切割 */public static void functionDemo_2(){String str = "zhangsanttttxiaoqiangmmmmmmzhaoliu";String[] names = str.split("(.)\\1+");for(String name : names){System.out.println(name);}}

3、替换:用replaceAll方法。

应用事例

        /* * 替换  * 把电话号码的第4位到第7位用*号替换 */public static void functionDemo_3() {String tel = "15800001111";//158****1111;tel = tel.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");System.out.println(tel);}

4、获取:将字符串中的符合规则的子串取出。
步骤
 1、 将正则规则进行对象的封装。 
      Pattern p = Pattern.compile("a*b");
 2、通过正则对象的matcher方法字符串相关联。获取要对字符串操作的匹配器对象Matcher .
        Matcher m = p.matcher("aaaaab");
  3、通过Matcher匹配器对象的方法对字符串进行操作。
        boolean b = m.matches();
应用事例
        /* * 获取  * 获取字符串中三个字母组成的单词 *  */public  static void functionDemo_4() {String str = "da jia hao,ming tian bu fang jia!";String regex = "\\b[a-z]{3}\\b";//1,将正则封装成对象。Pattern p = Pattern.compile(regex);//2, 通过正则对象获取匹配器对象。 Matcher m = p.matcher(str);//使用Matcher对象的方法对字符串进行操作。//既然要获取三个字母组成的单词 //查找。 find();System.out.println(str);while(m.find()){System.out.println(m.group());//获取匹配的子序列System.out.println(m.start()+":"+m.end());}}


小练习

 网页爬虫:其实就一个程序用于在互联网中获取符合指定规则的数据。 
 爬取邮箱地址。

public class RegexTest2 {public static void main(String[] args) throws IOException {List<String> list = getMailsByWeb();for(String mail : list){System.out.println(mail);}}public static List<String> getMailsByWeb() throws IOException {//1,读取源文件。URL url = new URL("http://192.168.1.100:8080/myweb/mail.html");BufferedReader bufIn = new BufferedReader(new InputStreamReader(url.openStream()));//2,对读取的数据进行规则的匹配。从中获取符合规则的数据.String mail_regex = "\\w+@\\w+(\\.\\w+)+";List<String> list = new ArrayList<String>();Pattern p = Pattern.compile(mail_regex);String line = null;while((line=bufIn.readLine())!=null){Matcher m = p.matcher(line);while(m.find()){//3,将符合规则的数据存储到集合中。list.add(m.group());}}return list;}public static List<String>  getMails() throws IOException{//1,读取源文件。BufferedReader bufr = new BufferedReader(new FileReader("c:\\mail.html"));//2,对读取的数据进行规则的匹配。从中获取符合规则的数据.String mail_regex = "\\w+@\\w+(\\.\\w+)+";List<String> list = new ArrayList<String>();Pattern p = Pattern.compile(mail_regex);String line = null;while((line=bufr.readLine())!=null){Matcher m = p.matcher(line);while(m.find()){//3,将符合规则的数据存储到集合中。list.add(m.group());}}return list;}}

                                                                                   反射
反射技术

        Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类中的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
 
应用场景
        已经可以使用的应用程序,不能再进行代码的加入了。后期我们新的功能加入程序时,就使用到了反射技术。
        

常用的作法:提供一个配置文件,来供以后实现此程序的类来扩展功能。对外提供配置文件,让后期出现的子类直接将类名字配置到配置文件中即可。

原理图



 
反射用到的类——Class类(描述字节码文件的对象)
       Class类描述的信息:类的名字,类的访问属性,类所属于的包名,字段名称的列表,方法名称的列表等。每一个字节码就是class的实例对象。

图解


获取Class对象的三种方式
        
方式一:
        通过对象的getClass方法进行获取。

        想要用这种方式,必须要明确具体的类,并创建对象。

public static void getClassObject_1(){Person p = new Person();Class clazz = p.getClass();Person p1 = new Person();Class clazz1 = p1.getClass();System.out.println(clazz==clazz1);}
方式二:

        任何数据类型都具备一个静态的属性.class来获取其对应的Class对象。
 相对简单,但是还是要明确用到类中的静态成员。

 不够扩展。

public static void getClassObject_2() {Class clazz = Person.class;Class clazz1 = Person.class;System.out.println(clazz==clazz1);}
方式三:

         只要通过给定的类的 字符串名称就可以获取该类,更为扩展。
 可是用Class类中的方法完成。
 该方法就是forName.

 这种方式只要有名称即可,更为方便,扩展性更强。 

public static void getClassObject_3() throws ClassNotFoundException {String className = "cn.itcast.bean.Person";Class clazz = Class.forName(className);System.out.println(clazz);}

Class类中的方法
        static Class forName(String className)
        返回与给定字符串名的类或接口的相关联的Class对象。
        Class getClass()
        返回的是Object运行时的类,即返回Class对象即字节码对象
        Constructor getConstructor()
        返回Constructor对象,它反映此Class对象所表示的类的指定公共构造方法。
        Field getField(String name)
        返回一个Field对象,它表示此Class对象所代表的类或接口的指定公共成员字段。
        Field[] getFields()
        返回包含某些Field对象的数组,表示所代表类中的成员字段。
        Method getMethod(String name,Class… parameterTypes)
        返回一个Method对象,它表示的是此Class对象所代表的类的指定公共成员方法。
        Method[] getMehtods()
        返回一个包含某些Method对象的数组,是所代表的的类中的公共成员方法。
        String getName()
        以String形式返回此Class对象所表示的实体名称。
        String getSuperclass()
        返回此Class所表示的类的超类的名称
        boolean isArray()
        判定此Class对象是否表示一个数组
        boolean isPrimitive()
        判断指定的Class对象是否是一个基本类型。
        T newInstance()

        创建此Class对象所表示的类的一个新实例。

反射的应用

                早期:new时候,先根据被new的类的名称找寻该类的字节码文件,并加载进内存,

并创建该字节码文件对象,并接着创建该字节文件的对应的Person对象.

                     cn.itcast.bean.Person p = new cn.itcast.bean.Person();
                现在用反射的话

                String name = "cn.itcast.bean.Person";                //找寻该名称类文件,并加载进内存,并产生Class对象。                Class clazz = Class.forName(name);                //产生该类的对象                 Object obj  = clazz.newInstance();
问题:当获取指定名称对应类中的所体现的对象时,
    而该对象初始化不使用空参数构造该怎么办呢?
解决办法: 既然是通过指定的构造 函数进行对象的初始化,
  所以应该先获取到该构造函数。 通过字节码文件对象即可完成。

 该方法是:getConstructor(paramterTypes);

                 String name = "cn.itcast.bean.Person";//找寻该名称类文件,并加载进内存,并产生Class对象。Class clazz = Class.forName(name);//获取到了指定的构造函数对  象。Constructor constructor = clazz.getConstructor(String.class,int.class);//通过该构造器对象的newInstance方法进行对象的初始化。Object obj = constructor.newInstance("小明",38);
获取字节码文件中的字段

                public static void getFieldDemo() throws Exception {Class clazz = Class.forName("cn.itcast.bean.Person");Field field = null;//clazz.getField("age");//只能获取公有的,field = clazz.getDeclaredField("age");//只获取本类,但包含私有。 //对私有字段的访问取消权限检查。暴力访问。field.setAccessible(true);Object obj = clazz.newInstance();field.set(obj, 89);Object o = field.get(obj);System.out.println(o);
获取指定Class中的所有公共函数

public static void getMethodDemo() throws Exception {Class clazz = Class.forName("cn.itcast.bean.Person");Method[] methods  = clazz.getMethods();//获取的都是公有的方法。 methods = clazz.getDeclaredMethods();//只获取本类中所有方法,包含私有。 for(Method method : methods){System.out.println(method);}}

0 0