Java基础——反射机制、正则表达式

1 反射机制

这里写图片描述
这里写图片描述

Person类

package cn.itcast.bean;

public class Person {
    private int age;
    private String name;

    public Person() {
        super();
        // TODO Auto-generated constructor stub
        System.out.println("person run");
    }
    public Person(String name,int age) {
        super();
        this.age=age;
        this.name=name;
        System.out.println("person param run..."+this.name+":"+this.age);
    }
    public void show() {
        System.out.println(name+"...show run..."+age);
    }
    private void method() {
        System.out.println("method run");
    }
    public void paramMethod(String str,int num) {
        System.out.println("paramMethod run......"+str+":"+num);
    }
    public static void staticMethod() {
        System.out.println("static method run......");
    }

}
package cn.itcast.reflect.demo;

import cn.itcast.bean.Person;

/*
 * Java反射机制是在运行状态中,对于任意一个类(class文件),都能够知道这个类的所有属性和方法
 * 对于任意一个对象,都能够调用它的任意一个方法和属性
 * 这种动态获取信息以及动态调用对象的方法的功能称为java预言的反射机制
 *
 * 动态获取类中信息,就是java反射
 * 可以理解为对类的解剖
 * 
 * 要想要对字节码文件进行解剖,必须要有字节码文件对象
 * 如何获取字节码文件对象呢?
 * 
 * */
public class ReflectDemo {

    public static void main(String[] args) throws ClassNotFoundException {
        // TODO Auto-generated method stub
//      getClassObject_1();
//      getClassObject_2();
        getClassObject_3();
    }
    private static void getClassObject_3() throws ClassNotFoundException {
        // TODO Auto-generated method stub
        /*
         *3、 只要通过给定的类的字符串名称就可以获取该类,更为扩展
         * 是用Class类中的方法完成,该方法就是forName
         * 
         * */
        String className="cn.itcast.reflect.demo.Person";//它会到默认路径下找(bin目录或者path),所以这个路径名要写全
        Class clazz=Class.forName(className);
        System.out.println(clazz);



    }
    private static void getClassObject_2() {
        // TODO Auto-generated method stub
        /*
         * 2、任何数据类型都具备一个静态的属性,class来获取其对应的class对象
         * 相对简单,但是还是要明确用到类中的静态成员。还是不够扩展
         * 
         * 
         * */
        Class clazz=Person.class;

        Class clazz1=Person.class;
        System.out.println(clazz==clazz1);

    }
    /*
     * 获取字节码对象的方式:
     * 1、Object类中的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);
    }

}
package cn.itcast.reflect.demo;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class ReflectDemo2 {

    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
        // TODO Auto-generated method stub
//      creatNewObject();
        creatNewObject_2();
    }

    private static void creatNewObject_2() throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        // TODO Auto-generated method stub
//      cn.itcast.bean.Person p=new cn.itcast.bean.Person("小强",39);
        /*
         * 当获取指定名称对应类中的所体现的对象时
         * 而该对象初始化不使用空参数构造函数该怎么办?
         * 既然是通过指定的构造函数进行对象的初始化,
         * 所以应该先获取到该构造函数,通过字节码文件对象即可完成
         * 该方法是: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);



    }

    private static void creatNewObject() throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        // TODO Auto-generated method stub
//      早期: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();//调用空参构造函数


    }

}
package cn.itcast.reflect.demo;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class ReflectDemo3 {

    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        // TODO Auto-generated method stub
//      getMethodDemo();
//      getMethodDemo_2();
        getMethodDemo_3();
    }

    private static void getMethodDemo_3() throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        // TODO Auto-generated method stub
        //获取指定函数(有参数),并运行
        Class clazz=Class.forName("cn.itcast.bean.Person");
        Method method=clazz.getMethod("paramMethod", String.class,int.class);

        Object obj=clazz.newInstance();
        method.invoke(obj, "小强",89);


    }

    private static void getMethodDemo_2() throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        // TODO Auto-generated method stub
        //获取指定函数(函数没有参数),并运行
        Class clazz=Class.forName("cn.itcast.bean.Person");
        Method method=clazz.getMethod("show", null);//获取空参数函数一般方法
//      Object obj=clazz.newInstance();//获取对象,空参数构造函数(对象初始化)

        Constructor constructor=clazz.getConstructor(String.class,int.class);
        Object obj=constructor.newInstance("小明",39);//获取对象,有参数构造函数(对象初始化)
        method.invoke(obj, null);//运行指定函数
    }

    private static void getMethodDemo() throws ClassNotFoundException {
        // TODO Auto-generated method stub
        /*
         * 获取指定Class中的公共函数
         * 
         * */
        Class clazz=Class.forName("cn.itcast.bean.Person");

//      Method[]methods=clazz.getMethods();//获取的都是公有的方法(包括父类的方法)
        Method[]methods=clazz.getDeclaredMethods();//只获取本类中所有方法,包括私有
        for(Method method:methods) {
            System.out.println(method);
        }

    }

}
package cn.itcast.reflect.demo;

import java.lang.reflect.Field;

public class getField {

    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException, InstantiationException, IllegalAccessException {
        // TODO Auto-generated method stub
        getFieldDemo();
    }

    private static void getFieldDemo() throws ClassNotFoundException, NoSuchFieldException, SecurityException, InstantiationException, IllegalAccessException {
        // TODO Auto-generated method stub
        /*
         * 获取字节码文件中的字段
         * */
        Class clazz=Class.forName("cn.itcast.bean.Person");
//      Field field=clazz.getField("age");//只能获取公有的
        Field field=clazz.getDeclaredField("age");//只获取本类,但包含私有的

        /*Object obj=clazz.newInstance();
        Object o=field.get(obj);
        System.out.println(o);*///不能访问,因为age是私有属性

        //但可以通过下面这种方式,将私有字段的范文取消权限检查,暴力访问
        field.setAccessible(true);
        Object obj=clazz.newInstance();//初始化对象
//      field.set(obj, 90);//修改age属性值
        Object o=field.get(obj);
        System.out.println(o);



        System.out.println(field);//结果:private int cn.itcast.bean.Person.age

    }

}

2 反射的应用(扩展性极强)

主程序

package cn.itcast.reflect.test;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;

/*
 * 电脑运行
 * 
 * */

public class ReflectTest {

    public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException {
        // TODO Auto-generated method stub
        Mainboard mb=new Mainboard();
        mb.run();
        //每次添加一个设备都需要修改代码传递一个新创建的对象
//      mb.usePCI(new SoundCard());
        //能不能不修改代码就可以完成这个动作
        //不用new来完成,而是只获取其Class文件,在内部实现创建对象的动作
        File configFile=new File("PCI.properties");

        Properties prop=new Properties();
        FileInputStream fis=new FileInputStream(configFile);

        prop.load(fis);
        for(int x=0;x<prop.size();x++) {
            String pciName=prop.getProperty("pci"+(x+1));
            Class clazz=Class.forName(pciName);//用Class去加载这个pci子类
            PCI p=(PCI)clazz.newInstance();//这一步其实就相当于new 一个p对象

            mb.usePCI(p);
        }
        fis.close();
    }

}

Mainboard类

package cn.itcast.reflect.test;

public class Mainboard {
    public void run() {
        System.out.println("main board run...");
    }
    public void usePCI(PCI p) {
        if(p!=null) {
        p.close();
        p.open();
        }
    }

}

NetCard类

package cn.itcast.reflect.test;

public class NetCard implements PCI {

    @Override
    public void run() {
        // TODO Auto-generated method stub
        System.out.println("net run");
    }

    @Override
    public void close() {
        // TODO Auto-generated method stub
        System.out.println("net close");
    }

    @Override
    public void open() {
        // TODO Auto-generated method stub
        System.out.println("net open");
    }

}

SoundCard类

package cn.itcast.reflect.test;

public class SoundCard implements PCI{
    public void open() {
        System.out.println("sound open");
    }
    public void close() {
        System.out.println("sound close");
    }
    @Override
    public void run() {
        // TODO Auto-generated method stub
        System.out.println("sound run");
    }
}

接口类

package cn.itcast.reflect.test;

public interface PCI {
    public void run();
    public void close();
    public void open();
}

2 正则表达式

package cn.itcast.regex.demo;

/*
 * 正则表达式
 * 
 * 正则表达式用于操作字符串数据
 * 通过一些特定的符号来体现的。
 * 所以为了掌握正则表达式,必须要学习一些符号
 * 虽然简化了,但是阅读性差
 * 
 * */
public class RegexDemo {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        String qq="1234567";
//      checkQQ(qq);
        String regex="[1-9][0-9]{4,14}";//正则表达式
//      boolean b=qq.matches(regex);
//      System.out.println(qq+":"+b);

        String str="aooob";
        String reg="ao+b";//o+表示一个或多个o {4}表示4个  {4,}表示4个及以上  {4,8}表示4到8个
        boolean b=str.matches(reg);
        System.out.println(str+":"+b);
    }
    /*
     * 需求:定义一个功能对QQ号进行校验
     * 要求:长度5~15,只能是数字,0不能开头
     * 
     * 
     * */

    private static void checkQQ(String qq) {
        // TODO Auto-generated method stub
        int len=qq.length();
        if(len>=5&&len<=15) {
            if(!qq.startsWith("0")) {
                try {
                long l=Long.parseLong(qq);
                System.out.println(l+":正确");
                }catch(NumberFormatException e) {
                    System.out.println(qq+":含有非法字符");
                }

            }else {
                System.out.println(qq+":不能0开头");
            }

        }else {
            System.out.println(qq+":长度错误");
        }

    }


}
package cn.itcast.regex.demo;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexDemo2 {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        /*
         * 正则表达式对字符串的常见操作:
         * 1、匹配
         *      其实使用的就是String类中的matches方法
         * 2、切割
         *      其实使用的就是String类中的split方法
         * 
         * 3、替换
         *      其实使用的就是String类中的replaceAll()方法
         * 
         * 4、获取
         * 
         * */
//      funcitonDemo_1();//匹配
//      funcitonDemo_2();//切割
//      funcitonDemo_3();//替换
        funcitonDemo_4();//获取
    }
    private static void funcitonDemo_4() {
        // TODO Auto-generated method stub
        /*
         * 获取
         * 将正则规则进行对象的封装
         * Pattern p=Pattern.compile("a*b");
         *通过正则对象的matcher方法字符串相关联,获取要对字符串操作的匹配器对象matcher
         *Matcher m=p.matcher("aaaaab");
         *通过Matcher匹配器对象的方法对字符串进行操作
         *boolean b=m.matches();
         * 
         * 
         * */
        String str="da jia hao,ming tian bu fang jia";
        String regex="\\b[a-z]{3}\\b";//\\b是给中间匹配的对象加边界的
        //将正则封装成对象
        Pattern p=Pattern.compile(regex);
        //通过正则对象获取匹配器对象
        Matcher m=p.matcher(str);
        //使用Matcher对象的方法对字符串进行操作
        //既然要获取三个字母组成的单词
        //查找.find();
        while(m.find()) {
        System.out.println(m.group());//获取匹配的子序列
        System.out.println(m.start()+":"+m.end());//获取查找到对象的开始与结束位置
        }

    }


    private static void funcitonDemo_3() {
        // TODO Auto-generated method stub
        /*String str="zhangsantttttxiaoqiangmmmmmmmzhaoliu";
        str=str.replaceAll("(.)\\1+", "#");*/

        String str="zhangsantttttxiaoqiangmmmmmmmzhaoliu";
        str=str.replaceAll("(.)\\1+", "$1");//用$符号获取前面正则规则匹配后的内容

        String tel="15800001111";//
        tel=tel.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");//第一组用匹配的代替,中间四个用*代替,后面那组用匹配的代替

        System.out.println(tel);//结果:158****1111

//      System.out.println(str);

    }
    private static void funcitonDemo_2() {
        // TODO Auto-generated method stub
        /*String str="zhangsan    xiaoqiang    zhaoliu";
        String[]names=str.split(" +");*/

        /*String str="zhangsan.xiaoqiang.zhaoliu";
        String[]names=str.split("\\.");//\.表示转义成普通字符".",但\在字符串中就表示时是就是普通字符“\”,要想它具有转义符的作用就必须转义,需要被转义下才能
*/      
        String str="zhangsantttttxiaoqiangmmmmmmmzhaoliu";
        String[]names=str.split("(.)\\1+");//(.)将相同的字符串封装成一个组,而我们又不知道这个组中具体是什么,就用.代替,而这个字符不知道出现几次,就用\\1+转义后的代表这个组出现一次或多次


        for(String name:names) {
            System.out.println(name);
        }
    }
    /*
     * 演示匹配
     * */
    public static void funcitonDemo_1() {
//      匹配手机号码是否正确
        String tel="15842563360";
//      String regex="1[358][0-9]{9}";//[0-9]可以用"\\d"代替,因为\d表示数字,而在字符串中\表示转义(因此\d就是转义了的d),所以用转义过后的\d
        String regex="1[358]\\d{9}";
        boolean b=tel.matches(regex);
        System.out.println(tel+":"+b);
    }

}
package cn.itcast.regex.demo;

import java.util.TreeSet;

public class RegexTest {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        /*
         * 1、治疗口吃:我我...我我...我我我要...要要要要...要要要要...学学学学学
         * 2、对ip地址排序
         * 3、对邮件地址校验
         * 
         * */
//      test_1();
//      test_2();
        test_3();
    }


    //治疗口吃

    private static void test_1() {
        // TODO Auto-generated method stub
        String str="我我...我我...我我我要...要要要要...要要要要...学学学学学";
//      将字符串中的.去掉,用替换
        str=str.replaceAll("\\.", "");
//      替换叠词
        str=str.replaceAll("(.)\\1+", "$1");
        System.out.println(str);
    }
    /*
     * ip地址排序
     * 192.168.10.34 127.0.0.1 3.3.3.3 105.70.11.55
     * 
     * */
    private static void test_2() {
        // TODO Auto-generated method stub
        String ip_str="192.168.10.34  127.0.0.1  3.3.3.3  105.70.11.55";
        //1、为了让ip可以按照字符串顺序比较,只要让ip的每一段的位数相同
        //所以,补零,按照每一位所需做多0进行补充,每一段都加两个0
        ip_str=ip_str.replaceAll("(\\d+)","00$1");
        System.out.println(ip_str);
        //然后每一段保留数字3位
        ip_str=ip_str.replaceAll("0*(\\d{3})", "$1");
        //1、将ip地址切出
        String[]ips=ip_str.split(" +");
        TreeSet<String>ts=new TreeSet<String>();

        for(String ip:ips) {
//          System.out.println(ip);
            ts.add(ip);
        }
        for(String ip:ts) {
            System.out.println(ip.replaceAll("0*(\\d+)", "$1"));
        }
    }
    //对邮件地址校验
    private static void test_3() {
        // TODO Auto-generated method stub
        String mail="abc1@sina.com";
        String regex="[a-zA-Z0-9_]+@[a-zA-Z0-9]+(\\.[a-zA-Z]{1,3})+";
        boolean b=mail.matches(regex);
        System.out.println(mail+":"+b);
    }

}
package cn.itcast.regex.demo;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

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

    public static void main(String[] args) throws IOException {
        // TODO Auto-generated method stub
        List<String>list=getMails();
        for(String mail:list) {
            System.out.println(mail);
        }
    }

    private static List<String> getMails() throws IOException {
        // TODO Auto-generated method stub
//      读取源文件
        BufferedReader bufr=new BufferedReader(new FileReader("mail.html"));
//      URL url=new URL("http://192.168.1.100:8080/myweb/mail.html");
//      BufferedReader bufIn=new BufferedReader(new InputStreamReader(url.openStream()));
        //      对读取的数据进行规则的匹配,从中获取符合规则的数据
        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()) {
//              将符合规则的数据存储到集合中
                list.add(m.group());
            }
        }
        return list;
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值