反射机制
- java反射机制是在运行状态中,对于任意一个类(class文件),都能知道这个类的属性和方法
- 对于任意一个对象,都能调用它的任意一个方法和属性
- 这种动态获取的信息以及动态调用对象方法的功能称为java的反射机制
Class对象
获取Class对象的三种方式:
- Object类中的getClass()方法,必须明确具体的类,并创建对象
Person p = new Person();
Class clazz = p.getClass();
Person p1 = new Person();
Class clazz1 = p1.getClass();
//clazz == clazz1
- 任何数据类型都具备一个静态的属性,通过.class来获取对应的Class对象,需要明确用到类中的静态成员
Class clazz = Person.class;
- 通过Class类中的方法获取,只要通过给定的类的字符串名称就可以获取该类
String className = "it.cast.bean.Person";
Class clazz = Class.forName(className);
//通过空参构造函数生成对象
Object obj = clazz.newInstance();
//想要通过Person(String name,int age)构造函数生成对象
Constructor constructor = clazz.getConstructor(String.class,int.class);//获取指定参数类型的构造函数对象
Object obj = constructor.newInstance("小明",17);//通过该构造器对象的newInstance方法创建对象
获取字节码文件中的字段
Class clazz = Class.forName("it.cast.bean.Person");
Field field = clazz.getField("age");//获取公有的字段
Field field1 = clazz.getDeclaredField("age");//获取本类所有字段
//对私有字段的访问取消权限检查,暴力访问
field.setAccessible(true);
Object obj = clazz.newInstance();
field.set(obj,21);//setAge()
Object o = field.get(obj);//getAge()
获取指定Class中的公共函数
Class clazz = Class.forName("it.cast.bean.Person");
//获取一般空参方法
Method method = clazz.getMethod("show",null);
Object obj = clazz.newInstance();
method.invoke(obj,null);//调用show方法
//获取有参方法
Method method = clazz.getMethod("run",String.class,int.class);
Object obj = clazz.newInstance();
method.invoke(obj,"scz",17);
正则表达式
通过一些特定符号操作字符串数据
//检验qq号码是否合法,1:长度5-15位,2:全是数字,3:不能以0开头
String qq = "1234356";
String regex = "[1-9][0-9]{4,14}";
boolean b = qq.matches(regex);
符号规则
[abc]:a,b或c
[^abc]:除了a,b,c
.:任何字符
\d:数字0-9,注意要用到\d组合时要先用一个\转义,即\\d,任何带\的组合都是如此使用
\w:[a-z A-Z _ 0-9]
常见功能
- 匹配
matches()
即上面的qq号码检验
- 切割
String str = "scz fxl lzh az";
String names = str.split(" +");
for(String name : names){
System.out.println(name);
}
String str = "sczaaaaafxl$$$$$lzh2222az";
String names = str.split("(.)\\1+");
//组的概念,(.)\\1+,第一组为任意字符,并且出现了一次以上
- 替换
String str = "sczaaaaafxl$$$$$lzh2222aa";
String names = str.replaceAll("(.)\\1+","$1");
//$1:使用前一个参数的第一组符号替换,sczafxl$lzh2az
- 获取
Pattern p = Pattern.compile("a*b");
//将正则规则进行对象的封装
Matcher m = p.matcher("aaab");
//通过正则对象的matcher方法与字符串相关联,获取要对字符串进行操作的匹配器对象Matcher
boolean b = m.matches();
//通过Matcher匹配器对象的方法对字符串操作
String str = "da jia hao,ming tian fang jia";
String regex = "\\b[a-z]{3}\\b";
//\\b为单词边界,这样只会取字母长度为3的符合正则的单词
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(str);
while(m.find()){
System.out.println(m.group());//获取匹配的子序列
}
练习
- ip地址排序
String ip_str = "192.168.1.1 123.3.22.210 26.3.42.127 103.233.24.9";
//在每个连续的数字段前面加上00
ip_str = ip_str.replaceAll("(\\d+)","00$1");//用00+连续数字段替换原数字段
//00192.00168.001.001 00123.003.0022.00210 0026.003.0042.00127 00103.00233.0024.009
ip_str = ip_str.replaceAll("0*(\\d{3})","$1");
//用0个0或多个0后的连续数字段替换原数字段
//192.168.001.001 123.003.022.210 026.003.042.127 103.233.024.009
String[] ips = ip_str.split(" +");
TreeSet<String> ts = new TreeSet<String>();
for(String ip:ips){
ts.add(ip);
}
for(String ip:ips){
System.out.println(ip.replaceAll("0*(\\d+)","$1"));
}
- 网络爬虫
//读取源文件
BufferedReader bufr = new BufferedReader(new FileReader("c:\\mail.html"));
//对读取的数据进行规则的匹配,获取符合规则的数据
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;