java第23到25天----正则表达式,反射

知识总结

  • 1.转换流的编码
  • 2.流的编码
  • 3.网络通信的三要素
  • 4.TCP
  • 5.UDP

正则表达式

1.匹配

  • 使用的是String类中的boolean matches(String regex)方法
  • 实例一:匹配手机号,
  • 要求
    • 1.全部是数字
    • 2.是11位
    • 3.第二位不能是1,2,6,9,0
    • 4.第一位只能是1
public static void piPei() throws IOException {

		BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
		String qq = bufferedReader.readLine();
		String regex = "1[34578]\\d{9}";
		
		System.out.println(qq.matches(regex));
		bufferedReader.close();

实例二:可以在b和k之间有零个或多个o

//		X? X,一次或一次也没有 
//		X* X,零次或多次 
//		X+ X,一次或多次 
//		X{n} X,恰好 n 次 
//		X{n,} X,至少 n 次
    public static void piPei() throws IOException {
        String s = "boooooooooooooook";
		String regex = "bo*k";

		System.out.println(s.matches(regex));

		
	}

2.切割

  • 使用的是String类中的 String[] split(String regex)方法
  • 依据正则表达式的字符串来切割
    public static void qieGe() {
//		String string = "dhkjar    djkhser,as leir     uyf,aseliru";
//		String regex = ",";
		//实例要求按照空格切割
//		String string = "dhkjar    djkhser,as leir     uyf,aseliru";
//		String regex = " +";
		
		//实例:
		String string = "dhkjar.djkhser.as.leir.uyf.aseliru";
		String regex = "\\.";//.代表任意字符
		
		String[] strs = string.split(regex);
		for (String string2 : strs) {
			System.out.println(string2);
		}
	}

3.替换

  • 使用的是String类中的 String replaceAll(String regex, String replacement)
  • 把字符串中符合正则表达式的内容替换成第二个参数的内容
    public static void tiHuan() {
		// 实例:将连续超过三个数字的部分替换成*******
		String string = "helloworld1d333333goodboy3644747bingbing7697823456chenchen54646564zhangsan888888list";
		String regex = "\\d{4,}";
		String str = string.replaceAll(regex, "*");
		System.out.println(str);
	}

4.获取

    public static void huoQu() {
		//	获取连续超过四个字母的字符串
		String string = "hellow                  orld1d333333goodboy3644                   747bingbing7697823456ch                   enchen546               46564zhangsan8                88888list";
		String regex = "[a-zA-Z]{4,}";
		
		//	将正则表达式进行了简单的转化,但是Pattern本身没有获取数据的能力
		Pattern pattern =Pattern.compile(regex);
		
		//	有获取数据的能力
		Matcher matcher =  pattern.matcher(string);
		
		//matcher.find();//判断是否有符合要求的内容
		//matcher.group();//获取数据
		while (matcher.find()) {
			System.out.println(matcher.group());
		}
		
	}

反射

  • 反射:动态的获取类的字节码文件对象,对其成员进行抽象
  • 想做的:就是通过字节码文件对象,直接创建普通的对象
  • 1.获取字节码文件对象
  • 2.获取对象
    • a. 通过字节码文件对象,获取具体的实例对象
    • b. 获取具体的构造方法(通过从构造方法中抽象出来的类Constructor)
  • 3.获取具体的属性,并给属性赋值(通过从属性中抽象出来的类Field实现)
  • 4.获取具体的方法,并调用方法(通过从方法中抽象出来的类Method实现)
    反射原理

后面用到的Person类代码

public class Person {
	private String name;

	@Override
	public String toString() {
		return "Person [name=" + name + "]";
	}

	public Person(String name) {
		super();
		this.name = name;
	}

	public Person() {
		super();
		// TODO Auto-generated constructor stub
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	//非静态无参
	public void play() {
		System.out.println("play");
	}
	//非静态有参
	public void run(String number) {
		System.out.println("run"+number);
	}

	//静态有参
	public static void show(String number,int age) {
		System.out.println("show"+number+age);
	}
}

1.获取字节码文件对象

  • a:通过Object提供的getClass方法得到字节码文件对象
    • 缺点,首先要有一个对象
    public static void fun1() {
		Person  person = new Person();
		Class class1 = person.getClass();
		System.out.println(class1);
		Person person2 = new Person();
		Class class2 = person.getClass();
		System.out.println(class1.equals(class2));
	}
  • b:每种数据类型都有一个class属性,通过它也可以获取当前类的字节码文件
    • 缺点:首先要知道这个类的名字
	public static void fun2() {
		Class class1 = Person.class;
		System.out.println(class1);
	}
  • c:Class提供的方法forName(字符串) 字符串的构成:包名+类名
    • 优点:只需提供一个当前类的字符串形式
	public static void fun3() throws ClassNotFoundException {
		Class class1 = Class.forName("com.qianfeng.test.Person");
		System.out.println(class1);
	}
  • 注意:字符串表示的类,在工作的时候,必须保证对应一个真正的类,否则报异常:ClassNotFoundException

2.获取对象

  • 通过普通方式
Person person = new Person("bingbing");
  • 通过反射
  • 1.无参的构造方法
    public static void fun1(Class class1) throws InstantiationException, IllegalAccessException{
		//创建实例对象
		//相当于在newInstance方法的内部调用了无参的构造方法
		Object person = class1.newInstance();
		//向下转型
		Person person2 = (Person)person;
		person2.setName("bingbing");
		System.out.println(person2.getName());
	}
  • 通过反射
  • 2.有参的构造方法
	public static void fun2(Class class1) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
		//这里的参数是实际的构造方法的参数的字节码文件
		Constructor constructor  = class1.getConstructor(String.class);
		Object person = constructor.newInstance("bingbing");//给定的实际参数
		System.out.println(person);
	}

3.获取具体的属性,并给属性赋值

  • 通过普通的方式
	public static void main(String[] args) {
		// 通过普通的方式
//		Person person = new Person();
//		person.setName("bingbing");
//		System.out.println(person.name);
  • 通过反射
    public static void     main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException,
			InstantiationException, IllegalAccessException {
		//1.获取字节码文件
		Class class1 = Class.forName("com.qianfeng.test.Person");
		//2.调出Field的方法得到对应的属性
		//参数就是那个实际的属性
		//注意:getField方法在获取属性的时候,必须保证属性存在,还要保证权限够大--public
		// Field field1 = class1.getField("name");

		//当属性是私有的,可以通过下面的设置,临时更改属性的权限,完成属性的获取
		Field field1 = class1.getDeclaredField("name");
		field1.setAccessible(true);
		// 3.给当前的属性指定一个具体的实例对象
		Person person1 = (Person)class1.newInstance();
		System.out.println(person1);
		//4.将filed1指定给person1
		//第一个参数是field对应的具体的实例对象 第二个参数是赋的具体的值
		field1.set(person1, "bingbing");
		System.out.println(field1.get(person1));
		System.out.println(person1.getName());
		
		//3.给当前的属性指定一个具体的实例对象
		Object person2 = class1.newInstance();
		//4.将filed1指定给person2
		//第一个参数是field对应的具体的实例对象 第二个参数是赋的具体的值
		field1.set(person2, "chenchen");
		System.out.println(field1.get(person2));
	}

4.获取具体的方法,并调用方法

  • 调用普通的方法
		Person person = new Person();
		person.run("123");
  • 使用反射
调用非静态的无参方法
	public static void fun1(Class class1) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
		//第一个参数:对应的方法的具体名字   第二个参数:具体方法参数的字节码文件对象
		Method method = class1.getMethod("play");
		
		//创建实例对象
		Constructor constructor = class1.getConstructor(String.class);
		Object person = constructor.newInstance("bingbing");
		
		//调用方法
		//第一个参数:给当前方法指定的具体对象   第二个参数:方法的具体参数
		method.invoke(person);
	}
调用非静态的有参方法
	public static void fun2(Class class1) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
		//第一个参数:对应的方法的具体名字   第二个参数:具体方法参数的字节码文件对象
		Method method = class1.getMethod("run",String.class);
		
		//创建实例对象
		Constructor constructor = class1.getConstructor(String.class);
		Object person = constructor.newInstance("bingbing");
		
		//调用方法
		//第一个参数:给当前方法指定的具体对象   第二个参数:方法的具体参数
		method.invoke(person,"123");
	}
调用静态的有参方法
	public static void fun3(Class class1) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
		//第一个参数:对应的方法的具体名字   第二个参数:具体方法参数的字节码文件对象
		//注意:所有数据类型都有自己的字节码文件对象.
		Method method = class1.getMethod("show",String.class,int.class);
		//调用方法
		//第一个参数:给当前方法指定的具体对象   第二个参数:方法的具体参数
		method.invoke(null, "苹果",222);
	}

代理

  • 作用:根据OCP(对扩展开发,对修改关闭)的原则,在不改变原来类的基础上,给这个类增加额外的功能

静态代理

  • 作用:可以实现代理
  • 缺点:代理对象要保证跟目标对象实现同样的接口,在维护的时候两个对象都要维护,而且代理对象实现的接口是死的,这是如果要给想实现不同功能的多个目标添加代理对象的话,要添加很多个类
public class Test {
	public static void main(String[] args) {
		Bingbing bingbing = new Bingbing();
		//bingbing.findHouse();
		
		Chenchen chenchen = new Chenchen();
		//chenchen.findHouse();
		
		Agent agent = new Agent(bingbing);
		agent.findHouse();
	}
}

interface TestInter {
	public void findHouse();
}

class Bingbing implements TestInter {

	@Override
	public void findHouse() {
		
		System.out.println("冰冰到西三旗找房");

	}
}

class Chenchen implements TestInter {

	@Override
	public void findHouse() {
		System.out.println("晨晨到宝盛里找房");

	}

}

//代理类
public class Agent implements TestInter{
	private TestInter persom;
	
	
	public Agent(TestInter persom) {
		super();
		this.persom = persom;
	}


	@Override
	public void findHouse() {
		// TODO Auto-generated method stub
		System.out.println("扣一半房租作为中介费");
		
		this.persom.findHouse();
		
		System.out.println("哈哈大笑");
	}
}

动态代理

  • 动态代理
    *要实现InvocationHandler接口
  • 调用动态代理的方法实现功能
  • 动态生成代理对象的方法–通过JDK内置的java.lang.reflect.Proxy动态代理类完成代理对象的创建
  • 参数一:这里代表类加载器,代理类的类加载器要与目标类的类加载器一致,类加载器用来装载内存中的字节码文件
  • 参数二:代理类的与目标类实现的接口必须相同,既指定给代理类的接口,目标类必须实现了
  • 参数三:代理类的构造方法生成的对象–主意:指定给构造方法的参数要使用Object
下面要用到的类
interface TestInter {
	public void findHouse();
}

class Bingbing implements TestInter {

	@Override
	public void findHouse() {
		
	
		System.out.println("冰冰到宝盛里找房");

	}
}


通过新写一个具体类的方式完成动态代理
public class Test {
	public static void main(String[] args) {
		TestInter bingbing = new Bingbing();
		TestInter agent = (TestInter)Proxy.newProxyInstance(bingbing.getclass.getClassLoader(),new Class[] {TestInter.class},new Agent(bingbing));
		//代理对象调动方法的时候,invoke方法会自动被调用
		agent.findHouse();
	}
    
}
public class Agent implements InvocationHandler{
	private Object person;
	
	
	
	public Agent(Object person) {
		super();
		this.person = person;
	}



	@Override
	/**
	 * 接口中的方法
	 * 主要:这个方法在调用接口方法的时候,会自动调动
	 * 参数一:代理对象的引用
	 * 参数二:目标对象的方法
	 * 参数三:目标对象的参数
	 */
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		// TODO Auto-generated method stub
		System.out.println("扣一半房租作为中介费");
		
		//通过反射的方法调用具体的对象的方法
		Object object = method.invoke(person, args);
		
		System.out.println("哈哈大笑");
		
		return object;
	}
	
}
通过匿名内部类的方式完成动态代理
public class Test {
	public static void main(String[] args) {
		TestInter bingbing = new Bingbing();
		TestInter agent = (TestInter)Proxy.newProxyInstance(bingbing.getClass().getClassLoader(), new Class[] {TestInter.class},new InvocationHandler() {
			
			@Override
			public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
				System.out.println("扣一半房租做中介费");
				// TODO Auto-generated method stub
				//通过反射的方法调用具体对象的方法
				Object object = method.invoke(bingbing, args);
				
				System.out.println("哈哈大笑");
				
				return object;
			}
		});
		agent.findHouse();
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值