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


                                            ------- 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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值