Java基础——反射机制、正则表达式
来源:互联网 发布:c语言 http post json 编辑:程序博客网 时间:2024/05/16 19:36
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; }}
阅读全文