正则表达式,Java反射相关
2015-06-30 22:28
549 查看
十二、正则表达式:
1、作用:用于操作字符串的规则。
2、好处:
可以简化对字符串的复杂操作。
3、弊端:
符号定义越多,正则表达式越长,阅读性越差。
4、示例:
见RegexDemo.java
<span style="font-family:Microsoft YaHei;font-size:12px;">/* 正则表达式 作用:用于操作字符串的规则 特点:用一些特定的符号来表示一些代码操作,简化书写 学习正则表达式就是学习一些特殊符号的使用 好处:可以简化对字符串的复杂操作 具体操作功能: 1、匹配: String类中的matches(String regex)方法 用规则匹配整个字符串,只要有一处不符合规则就匹配结束,返回false 2、切割: String类中的split(String regex)方法 3、替换: String类中的replaceAll(String regex,String replacement)方法 */ class RegexDemo{ public static void main(String[] args){ checkQQ(); } //3、替换------------------------------------------------------------------------------------------- public static void replaceAllDemo(){ String str = "seven12943907lin13777777777";//将字符串中的数字替换成"#" String regex = "\\d{5,}"; String newstr = "#"; String str = "zhangsanXXlisiAAwangwu";//将叠词替换成"&" String regex = "(.)\\1+"; String newstr = "&"; String str = "zhangsanXXlisiAAwangwu";//将重叠字符替换成单个字符 String regex = "(.)\\1+"; String newstr = "$1";//"$1"提取前一规则中的第一个组 str = str.replaceAll(regex,newstr); System.out.println(str); } //2、切割------------------------------------------------------------------------------------------- /* 切割字符串 */ public static void splitDemo(){ //String str = "zhangsan lisi wangwu"; //String regex = " +";//按照多空格进行切割 //String str = "zhangsan.lisi.wangwu"; //String regex = "\\.";//"."是正则表达式中的特殊符号,"\."是正则表达式中的普通的点 //String str = "zhangsan\\lisi\\wangwu"; //String regex = "\\\\"; //为了可以让规则的结果被重用,将要重用的部分用小括号括起来,封装成一个组 //组的出现都有默认编号,组内的结果可以被重新使用 //从1开始,想要使用已有的组可以通过"\n(n就是组的编号)"的形式来获取 String str = "zhangsanXXlisiAAwangwu"; String regex = "(.)\\1+";//按照叠词切割,"+"表示出现一次或多次 String[] arr = str.split(regex); for(String s:arr){ System.out.println(s); } } //1、匹配------------------------------------------------------------------------------------------- /* 匹配手机号 手机号段:13xxx 15xxx 18xxx */ public static void checkTel(){ String tel = ""; String regex = "1[358]\\d{9}"; System.out.println(tel.matches(regex)); } /* 对QQ号码进行校验 要求:5~15位 0不能开头,只能是数字 */ //方法二:使用正则表达式 public static void checkQQ(){ String qq = ""; String regex = "[1-9][0-9]{4,14}"; boolean flag = qq.matches(regex); if(flag) System.out.println("qq:"+qq); else System.out.println("格式错位"); } /* //方法一:使用了String类中的方法,进行组合完成了需求,但是代码过于复杂 public static void checkQQ(){ String qq = "1642313132"; int len = qq.length(); if(len>=5 && len<=15){ if(!qq.startWith("0")){ try{ long l = Long.parseLong(qq); System.out.println("qq:"+l); } catch(NumberFormatException e){ System.out.println("出现非法字符"); } //char[] arr = qq.toCharArray(); //boolean flag = true; //for(int x=0;x<arr.length;x++){ // if(!(arr[x]>='0' && arr[x]<='9')){ // flag = false; // } //} //if(flag){ // System.out.println("qq:"+qq); //}else{ // System.out.println("出现非法字符"); //} }else{ System.out.println("不能以0开头"); } }else{ System.out.println("号码5~15位"); } } */ }</span>
<span style="font-family:Microsoft YaHei;font-size:12px;">/* 正则表达式 具体操作功能: 4、获取: 将字符串中符合规则的子串取出 操作步骤: (1)将正则表达式封装成对象 (2)让正则对象和要操作的字符串相关联 (3)关联后,获取正则匹配引擎 (4)通过引擎对符合规则的子串进行操作,比如取出 注意: 同一个匹配器,使用同一个指针 */ import java.util.regex.*; class RegexDemo{ public static void main(String[] args){ getDemo(); } public static void getDemo(){ String str = "baby now take me into your loving arms"; String regex = "\\b[a-zA-Z]{3}\\b";//取出三个字母组成的单词 //将规则封装成对象 Pattern p = Pattern.compile(regex); //让正则对象和要作用的字符串相关联,获取匹配器子串 Matcher m = p.matcher(str); //其实String类中的matches方法,就是用Pattern和Matcher对象来完成的 //只是被String的方法封装后使用比较简单,但是功能单一 //System.out.println(m.matches()); //find方法将规则作用到字符串上,并进行符合子串的查找,返回boolean //System.out.println(m.find()); //group方法用于获取匹配后的结果 //System.out.println(m.group()); while(m.find()){ System.out.println(m.group()); System.out.println(m.start()+"..."+m.end());//获取子串的起始位置,含头不含尾 } } }</span>
十三、Java反射:
1、定义:Java程序中的各个Java类属于同一类事物,描述这类事物的Java类名就是Class
对象是由字节码创建的
2、获取字节码对应的实例对象的方法:
(1)类名.class,例如:System.class
(2)对象.getClass(),例如:new Date().getClass();
(3)Class.forName("类名"),例如:Class.forName("java.util.Date");
3、九个预定义的Class实例对象:
八个基本数据类型加上void
只要是源程序中出现的类型,都有各自的Class实例对象,例如:void、int[]...
4、反射:
反射就是把Java类中的各种成分映射成相应的Java类。
一个类中的每个成员都可以用相应的反射API类的一个实例对象来表示,通过调用Class类的方法可以得到这些实例对象。
(1)Constructor类:代表某个类中的一个构造方法
a、得到某个类所有的构造方法:Constructor[] constructors = Class.forName("java.lang.String").getConstructors();
b、得到一个构造方法:Constructor constructor = Class.forName("java.lang.String").getConstructor(StringBuffer.class);//具体哪一个构造方法,区别在于参数不同
c、创建实例对象:
通常方式:String
str = new String(new StringBuffer("abc"));
反射方式:String
str = (String)Class.forName("java.lang.String").getConstructor(StringBuffer.class).newInstance(new StringBuffer("abc"));
d、使用不带参数的构造方法,可以直接使用:
Class.newInstance();
该方法内部先得到默认的构造方法,然后用该构造方法创建实例对象,该方法用到了缓存机制
(2)Field类:成员变量
a、获取公有成员:Field fY = pt.getClass().getField("y");
System.out.println(fY.get(pt));
b、获取私有成员:Filed fX = pt.getClass().getDeclaredField("x");
fX.setAccessible(true);//暴力反射,否则不可用
System.out.println(fX.get(pt));
c、Field[] fields = obj.getClass().getFields();
for(Field
f : fields){
if(field.getType()==String.class){
f.set(obj,(String)f.get(obj).replace('b','a'));
}
}
(3)Method类:代表某个类中的成员方法
a、得到类中的某一个方法:Method charAt = Class.forName(java.util.String).getMethod("charAt",int.class);
b、调用方式:
通常方式:System.out.println(str.charAt(1));
反射方式:System.out.println(charAt.invoke(str,1));
当invoke的第一个参数是"null"时,说明这是一个静态方法,静态方法的调用不需要对象
(4)Array类:数组的反射
a、具有相同维数和元素类型的数组属于同一个类型,即具有相同的Class实例对象
b、代表数组的Class实例对象的getSuperclass()方法返回的父类为Object类对应的Class
c、基本类型的一维数组可以看作是Object的子类对象使用,但不可以当作Object[]类型使用;
非基本类型的一维数组,可以当作Object类型使用,也可以当作Object[]类型使用
5、框架等具体示例,详见ReflectDemo.java
<span style="font-family:Microsoft YaHei;font-size:12px;">/* 反射(Reflect)示例 */ import java.lang.reflect.Array; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.Arrays; class ReflectDemo{ public static void main(String[] args) throws Exception{ /* Constructor构造方法类 示例参数为StringBuffer */ Constructor cons = String.class.getConstructor(StringBuffer.class);//1、获取方法时指定类型 //编译器,只看代码的编译,不管运行,所以需要指定类型 String str1 = (String)cons.newInstance(new StringBuffer("abc"));//2、调用方法时需要传入上面同样类型的对象 System.out.println(str1.charAt(2)); /* Field成员变量类 */ ReflectPoint pt1 = new ReflectPoint(3,5); Field fY = pt1.getClass().getField("y"); //fY不是对象身上的变量,而是类(字节码文件)上的,要用它去取某个对象上的值 System.out.println(fY.get(pt1)); Field fX = pt1.getClass().getDeclaredField("x");//获取私有变量 fX.setAccessible(true);//暴力反射,否则不可用 System.out.println(fX.get(pt1)); System.out.println(pt1.toString()); changeStringValue(pt1); System.out.println(pt1.toString()); /* Method方法类 */ Method methodCharAt = Class.forName("java.lang.String").getMethod("charAt",int.class);//"..."可变参数,有几个参数写几个 System.out.println(methodCharAt.invoke(str1,1));//获取字节码文件中的方法,包装成一个对象,再调用该对象中的方法invoke;第一个参数是作用的对象,后面是参数列表 //调用main方法 //普通方式 //TestArguments.main(new String[]{"seven","da","lin"}); //反射方式 String startingClassName = args[0];//运行时需要传入一个参数"TestArguments",这是要启动的类名,开发过程中我们一般不知道,直接从配置文件中加载 Method mainMethod = Class.forName(startingClassName).getMethod("main",String[].class); mainMethod.invoke(null,new Object[]{new String[]{"seven","da","lin"}});//如果不用Object封装一下,java会将发来的String数组解包一次,认为是三个String参数;封装之后,解包一次,就是一个String数组 //mainMethod.invoke(null,(Object)new String[]{"seven","da","lin"});//这样亦可 /* Array数组类 */ int[] a1 = new int[]{1,2,3}; int[] a2 = new int[4]; int[][] a3 = new int[2][3]; String[] a4 = new String[]{"a","b","c"}; System.out.println(a1.getClass().getName() == a2.getClass().getName());//true System.out.println(a1.getClass().getName() == a3.getClass().getName());//false System.out.println(a1.getClass().getName() == a4.getClass().getName());//false System.out.println(a1.getClass().getName());//获取类名,"[I"整型数组 System.out.println(a1.getClass().getSuperclass().getName());//结果"java.lang.Object",获取父类名称 System.out.println(a4.getClass().getSuperclass().getName());//结果"java.lang.Object" //数组类型是Object的子类,把数组看成Object对象,Object类型数组可以存放Object对象 Object obj1 = a1;//可以,a1是一个数组对象 Object obj2 = a4;//可以,a4是一个数组对象 //Object[] obj3 = a1;//不可以,obj3是一个对象数组,a1只是一个数组对象 Object[] obj4 = a3;//可以,a3可以看成一个数组,其中存的是数组对象 Object[] obj5 = a4;//可以,String本就是对象,String[]就是一个对象数组 System.out.println(a1);//"[I@______"下划线为hashCode值 System.out.println(a4);//"[Ljava.lang.String;@______" System.out.println(Arrays.asList(a1));//"[[I@______]",a1是一个int[],整体是一个对象 System.out.println(Arrays.asList(a4));//"[a,b,c]",a4是一个String[],其中的每个String可以看成一个对象 //使用反射的方式打印数组 printObject(a1); printObject(a4);//"a\n b\n c\n" printObject("xyz");//"xyz" Object[] a = new Object[]{"seven",1};//Object数组中可以存放各种类型 System.out.println(a[0].getClass().getName()); System.out.println(a[1].getClass().getName()); } /* Array练习: */ private static void printObject(Object obj){ Class c = obj.getClass(); if(c.isArray()){ int len = Array.getLength(obj); for(int i=0;i<len;i++){ System.out.println(Array.get(obj,i));//obj[i] } }else{ System.out.println(obj); } } /* Field练习: 将任意一个对象中的所有String类型的成员对应的字符串内容中的“b”改成“a” */ private static void changeStringValue(Object obj) throws Exception{ Field[] fields = obj.getClass().getFields(); for(Field field : fields){ //if(field.getType().equals(String.class)){ if(field.getType()==String.class){//字节码使用"=="比较 String oldstr = (String)field.get(obj); String newstr = oldstr.replace('b','a'); field.set(obj,newstr); } } } } public class ReflectPoint{ private int x; public int y; public String str1 = "ball"; public String str2 = "basketball"; public String str3 = "soccer"; public ReflectPoint(int x,int y){ this.x = x; this.y = y; } public String toString(){ return str1+","+str2+","+str3; } } public class TestArguments{ public static void main(String[] args){ for(String arr : args){ System.out.println(arr); } } } </span>
相关文章推荐
- Eclipse插件-PatternBox
- spring+struts+hibernate
- java自带的MD5加密 以及jsMD5加密
- 如何理解: java的import ???
- 软件包javax.servlet不存在的解决办法
- javaweb——Filter(过滤器)学习
- java多线程通信同步之多Condition通信
- Struts2(九)OGNL表达式
- java 对象排序
- Java实现websocket
- java多线程之线程间同步通信
- 我们如何看Java的开发环境???
- @Autowired和@Resource装配
- struts的titles框架
- spring mvc 数据绑定 400错误
- 内存分配与回收策略
- java中key值可以重复的map---IdentityHashMap
- Eclipse UML小工具AmaterasUML的配置和使用
- CXF+Spring+JAXB+Json构建Restful服务
- JAVA学习第8天