概述
一 递归
1. 就是函数自身调用自身 (就是在栈内存中不断的加载同一个函数)
2. 什么时候用递归呢?
当一个功能被重复使用 而每一次使用该功能时的参数不确定 都由上次的功能元素结果来确定
简单说: 功能内部又用到该功能 但是传递的参数值不确定(每次功能参与运算的未知内容不确定)
3. 递归的注意事项
1> 一定要定义递归的条件
2> 递归的次数不要过多 容易出现 StackOverflowError 栈内存溢出错误
二 反射
其实就是动态加载一个指定的类 并获取该类中的所有的内容 而且将字节码文件封装成对象 并将字节码文件中的内容都封装成对象 这样便于操作这些成员 简单说: 反射技术可以对一个类进行解剖
1. 反射的好处
大大的增强了程序的扩展性
2. 反射的基本步骤
1> 获得Class对象 就是获取到指定的名称的字节码文件对象
2> 实例化对象 获得类的属性, 方法或构造函数
3> 访问属性, 调用方法, 调用构造函数创建对象
3. 获取这个Class对象 有三种方式
1> 通过每个对象都具备的方法getClass来获取 弊端: 必须要创建该类对象 才可以调用getClass方法(不利于程序的扩展 因为都需要在程序使用具体的类来完成)
2> 每一个数据类型(基本数据类型和引用数据类型) 都有一个静态的属性class 弊端: 必须要先明确该类(不利于程序的扩展 因为都需要在程序使用具体的类来完成)
3> 使用的Class类中的方法 (静态的forName方法) 指定什么类名 就获取什么类字节码文件对象 这种方式的扩展性最强 只要将类名的字符串传入即可
// 根据给定的类名来获得 用于类加载
String classname = "cn.itcast.reflect.Person"; // 来自配置文件
Class clazz = Class.forName(classname); // 此对象代表Person.class
// 如果拿到了对象 不知道是什么类型 用于获得对象的类型
Object obj = new Person();
Class clazz1 = obj.getClass(); // 获得对象具体的类型
// 如果是明确地获得某个类的Class对象 主要用于传参
Class clazz2 = Person.class;
4. 反射的用法
1> 需要获得java类的各个组成部分 首先需要获得类的Class对象 获得Class对象的三种方式
Class.forName(classname) ---> 用于做类加载
obj.getClass() ---> 用于获得对象的类型
类名.class ---> 用于获得指定的类型 传参用
2> 反射类的成员方法
Class clazz = Person.class;
Method method = clazz.getMethod(methodName, new Class[]{paramClazz1, paramClazz2});
method.invoke();
3> 反射类的构造函数
Constructor con = clazz.getConstructor(new Class[]{paramClazz1, paramClazz2, ...});
con.newInstance(params...);
4> 反射类的属性
Field field = clazz.getField(fieldName);
field.setAccessible(true);
field.setObject(value);
5. 获取了字节码文件对象后 最终都需要创建指定类的对象
创建对象的两种方式(其实就是对象在进行实例化时的初始化方式)
1> 调用空参数的构造函数: 使用了Class类中的newInstance()方法
2> 调用带参数的构造函数: 先要获取指定参数列表的构造函数对象 然后通过该构造函数的对象的newInstance(实际参数) 进行对象的初始化
综上所述 第二种方式 必须要先明确具体的构造函数的参数类型 不便于扩展 所以一般情况下 被反射的类 内部通常都会提供一个公有的空参数的构造函数
// 如何生成获取到字节码文件对象的实例对象 Class clazz = Class.forName("com.huangyi.domain.Person"); //类加载 // 直接获得指定的类型 clazz = Person.class; // 根据对象获得类型 Object obj = new Person("zhangsan", 19); clazz = obj.getClass(); Object obj = clazz.newInstance(); //该实例化对象的方法调用就是指定类中的空参数构造函数 给创建对象进行初始化 当指定类中没有空参数构造函数时 使用method_2(); public static void method_2() throws Exception { Class clazz = Class.forName("com.huangyi.domain.Person"); //既然类中没有空参数的构造函数 那么只有获取指定参数的构造函数 用该函数来进行实例化 //获取一个带参数的构造器 Constructor constructor = clazz.getConstructor(String.class, int.class); //想要对对象进行初始化 使用构造器的方法newInstance(); Object obj = constructor.newInstance("zhagnsan", 30); //获取所有构造器 Constructor[] constructors = clazz.getConstructors(); //只包含公共的 constructors = clazz.getDeclaredConstructors(); //包含私有的 for(Constructor con : constructors) { System.out.println(con); } }
6. 反射指定类中的方法
//获取类中所有的方法 public static void method_1() throws Exception { Class clazz = Class.forName("com.huangyi.domain.Person"); Method[] methods = clazz.getMethods(); //获取的是该类中的公有方法和父类中的公有方法 methods = clazz.getDeclaredMethods(); //获取本类中的方法 包含私有方法 for(Method method : methods) { System.out.println(method); } } //获取指定方法 public static void method_2() throws Exception { Class clazz = Class.forName("com.huangyi.domain.Person"); //获取指定名称的方法 Method method = clazz.getMethod("show", int.class, String.class); //想要运行指定方法 当然是方法对象最清楚 为了让方法运行 调用方法对象的invoke方法即可 但是方法运行必须要明确所属的对象和具体的实际参数 Object obj = clazz.newInstance(); method.invoke(obj, 39, "hehehe"); //执行一个方法 } //想要运行私有方法 public static void method_3() throws Exception { Class clazz = Class.forName("com.huangyi.domain.Person"); //想要获取私有方法 必须用getDeclearMethod(); Method method = clazz.getDeclaredMethod("method", null); // 私有方法不能直接访问 因为权限不够 非要访问 可以通过暴力的方式 method.setAccessible(true); //一般很少用 因为私有就是隐藏起来 所以尽量不要访问 } //反射静态方法 public static void method_4() throws Exception { Class clazz = Class.forName("com.huangyi.domain.Person"); Method method = clazz.getMethod("function", null); method.invoke(null, null); }
三 正则表达式
其实是用来操作字符串的一些规则 (其实更多是用正则解决字符串操作的问题)
1. 好处: 正则的出现 对字符串的复杂操作变得更为简单
2. 特点: 将对字符串操作的代码用一些符号来表示 只要使用了指定符号 就可以调用底层的代码对字符串进行操作 符号的出现 简化了代码的书写
3. 弊端:符号的出现虽然简化了书写 但是却降低了阅读性
4. 常见操作
1> 匹配 其实用的就是String类中的matches方法
String reg = "[1-9][0-9]{4,14}";
boolean b = qq.matches(reg); //将正则和字符串关联对字符串进行匹配
2> 切割 其实用的就是String类中的split方法
3> 替换 其实用的就是String类中的replaceAll();
4> 获取
a. 先要将正则表达式编译成正则对象 使用的是Pattern中静态方法 compile(regex);
b. 通过Pattern对象获取Matcher对象
c. 使用Matcher对象中的方法即可对字符串进行各种正则操作
5. 常用符号
转载于:https://www.cnblogs.com/huangyi-427/p/4717381.html
最后
以上就是活力咖啡豆为你收集整理的Java 递归 反射 正则表达式的全部内容,希望文章能够帮你解决Java 递归 反射 正则表达式所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复