温故知新
1、Servlet生命周期
①、初始化阶段,调用init()方法
②、响应客户请求阶段,调用service()方法。由service()方法根据提交方式选择执行doGet()方法还是doPost()方法
③、终止阶段,调用destory()方法
2、Servlet容器装载Servlet的几种情况
1、Servlet容器启动时自动装载Servlet,实现只需要在web.xml文件中<Servlet></Servlet>间加入<loadon-startup>1</loadon-startup>,数字越小表示优先级越高
2、客户首次向Servlet发送请求
3、Servlet类文件被更新后,重新装载Servlet
3、Servlet与九大内置对象
4、Servlet高级
获取初始化参数
在web.xml中配置Servlet,可配置一些初始化参数。而在Servlet中可通过ServletConfig接口提供的方法获取这些参数
<init-param>
<param-name>username</param-name>
<param-value>admin</param-value>
</init-param>
<init-param>
<param-name>password</param-name>
<param-value>123456</param-value>
</init-param>
使用this.getInitParameter("username")获取参数
—————————————————————————————————————————————————————————————————————————————————
Java---反射
1、Class类的使用
类是对象,类是java.lang.Class类的实例对象
1 public class ClassDemo { 2 public static void main(String[] args) { 3 // Foo的实例对象表示 4 Foo foo = new Foo(); 5 6 // Foo类 也是一个实例对象 7 // 任何一个类都是Class的实例对象,这个实例对象有三种表示方式 8 9 // 第一种方式---实际表示任何一个类都有一个隐含的静态成员变量 10 Class c1 = Foo.class; 11 12 // 第二种方式---已知该类的对象通过getClass方法获取 13 Class c2 = foo.getClass(); 14 15 // 第三种方式---直接通过forName 16 Class c3 = null; 17 try { 18 c3 = Class.forName("com.Foo"); 19 } catch (ClassNotFoundException e) { 20 e.printStackTrace(); 21 } 22 23 // 官网 c1/c2/c3 表示Foo类的类类型(class type) c1==c2==c3 24 // 可以使用 c1/c2/c3 创建该类的对象实例 25 try { 26 // 需要有无参数的构造方法 27 Foo foo1 = (Foo) c1.newInstance(); 28 Foo foo2 = (Foo) c2.newInstance(); 29 Foo foo3 = (Foo) c3.newInstance(); 30 foo1.print(); 31 foo2.print(); 32 foo3.print(); 33 } catch (InstantiationException e) { 34 e.printStackTrace(); 35 } catch (IllegalAccessException e) { 36 e.printStackTrace(); 37 } 38 } 39 } 40 class Foo{ 41 void print(){ System.out.println("Foo类对象"); } 42 }
2、动态加载类
编译时刻加载类是静态加载类 —— 运行时刻加载类是动态加载类
编译时刻和运行时刻的区别:
new 创建对象 是静态加载类,在编译时刻就需要加载所有的可能使用到的类(通过动态加载类可以解决)
Class c = Class.forName("com.class"); 是动态加载类,通过类类型创建对象(Object obj = (Object)c.newInstance;)
3、方法的反射
1 public class ClassDemo { 2 public static void main(String[] args) { 3 4 Class c1 = int.class; // int 5 Class c2 = String.class; 6 Class c3 = double.class; 7 Class c4 = Double.class; 8 Class c5 = void.class; 9 10 System.out.println(c1.getName()); // 输出int 11 System.out.println(c2.getName()); // 输出java.lang.String 12 System.out.println(c2.getSimpleName());// 输出String 不包含包名的类的名称 13 System.out.println(c5.getName()); // 输出void 14 15 } 16 }
获取方法的信息
1 public class ClassUtil { 2 /* 3 打印类的信息,成员函数 4 * @param obj 该对象所属类的信息 5 * */ 6 public static void printClassMethodMessage(Object object) { 7 // 要获取类的信息 首先要获取类的类类型 8 Class c = object.getClass(); // 传递的是哪个子类的对象,c就是该子类的类类型 9 10 // 获取类名称 11 System.out.println("类名:" + c.getName()); 12 /* 13 * Method类,方法对象 14 * 一个成员方法就是一个Method对象 15 * getMethod()方法获取的是所有的public函数,包括父类继承而来的 16 * getDeclaredMethods()获取的是所有该类自己声明的方法,不问访问权限 17 * */ 18 Method[] ms = c.getMethods(); // c.getDeclaredMethods() 19 for (int i=0; i<ms.length; i++){ 20 // 得到方法的返回值类型的类类型 21 Class resultType = ms[i].getReturnType(); 22 System.out.println(resultType.getName() + " "); 23 // 得到方法的名称 24 System.out.println(ms[i].getName()+"("); 25 // 获取参数类型--->得到参数列表的类型的类类型 26 Class[] paramTypes = ms[i].getParameterTypes(); 27 for (Class class1 : paramTypes){ 28 System.out.println(class1.getName()+","); 29 } 30 System.out.println(")"); 31 } 32 } 33 } 34 35 public class Classdemo{ 36 public static void main(String[] args) { 37 String s = "hello"; 38 ClassUtil.printClassMethodMessage(s); 39 } 40 }
1)如何获取某个方法
方法的名称和方法的参数列表才能唯一决定某个方法
2)方法反射的操作
method.invoke(对象, 参数列表)
1 public class MethodDemo { 2 public static void main(String[] args) { 3 // 要获取print(int, int)方法, 1、要获取一个方法就是获取类的信息,获取类的信息首先要获取类的类类型 4 A a1 = new A(); 5 Class c = a1.getClass(); 6 // 2、获取方法 名称和参数列表来决定 7 // getMethod获取的是public的方法 8 // getDeclaredMethod 9 try { 10 // Method m = c.getMethod("print", new Class[]{int.class, int.class}); 11 Method m = c.getMethod("print", int.class,int.class); 12 Method m1 = c.getMethod("print", String.class, String.class); 13 Method m2 = c.getMethod("print"); 14 // 方法的反射操作 方法如果没有返回值返回null,有返回值返回具体的返回值 15 m.invoke(a1, 10, 20); 16 m1.invoke(a1, "hello","WORLD"); 17 m2.invoke(a1 , new Object[]{}); 18 } catch (Exception e) { 19 e.printStackTrace(); 20 } 21 } 22 } 23 24 public class A{ 25 public void print(){ 26 System.out.println("helloWorld!!!"); 27 } 28 29 public void print(int a, int b){ 30 System.out.println(a+b); 31 } 32 33 public void print(String a, String b){ 34 System.out.println(a.toUpperCase() + "," +b.toLowerCase()); 35 } 36 }
4、成员变量的反射
获取成员变量的信息
1 public class ClassUtil { 2 /* 3 打印类的信息,成员变量 4 * @param obj 该对象所属类的信息 5 * */ 6 public static void printClassFieldMessage(Object object) { 7 // 要获取类的信息 首先要获取类的类类型 8 Class c = object.getClass(); // 传递的是哪个子类的对象,c就是该子类的类类型 9 10 // 获取类名称 11 System.out.println("类名:" + c.getName()); 12 /* 13 * 成员变量也是对象 14 * java.lang.reflect.Field 15 * Field类封装了关于成员变量的操作 16 * getField方法获取的是所有的public的成员变量信息 17 * getDeclaredFields获取的是该类自己声明的成员变量的信息 18 * */ 19 /*Field[] fs = c.getFields();*/ 20 Field[] fs = c.getDeclaredFields(); 21 for (Field field : fs){ 22 // 得到成员变量的类型的类类型 23 Class fieldType = field.getType(); 24 String typeName = fieldType.getName(); 25 // 得到成员变量的名称 26 String fieldName = field.getName(); 27 System.out.println(typeName+" "+fieldName); 28 } 29 } 30 } 31 32 public class Classdemo{ 33 public static void main(String[] args) { 34 Integer n = 1; 35 ClassUtil.printClassFieldMessage(n); 36 } 37 }
5、构造函数的反射
获取构造函数信息
1 public class ClassUtil { 2 /* 3 打印对象的构造函数的信息 4 * */ 5 public static void printConMessage(Object object) { 6 Class c = object.getClass(); 7 8 /* 9 * 构造函数也是对象 10 * java.lang.Constructor中封装了构造函数的信息 11 * getConstructors获取所有的public的构造函数 12 * getDeclaredConstructors得到所有构造函数 13 * */ 14 /*Constructor[] ss = c.getConstructors();*/ 15 Constructor[] ss = c.getDeclaredConstructors(); 16 for (Constructor constructor : ss){ 17 System.out.println(constructor.getName() + "("); 18 // 获取构造函数的参数列表--->得到的是参数列表的类类型 19 Class[] paramTypes = constructor.getParameterTypes(); 20 for (Class class1 : paramTypes){ 21 System.out.println(class1.getName() + ","); 22 } 23 } 24 } 25 } 26 27 public class ClassDemos{ 28 public static void main(String[] args) { 29 ClassUtil.printConMessage("hello"); 30 ClassUtil.printConMessage(new Integer(1)); 31 } 32 }
6、通过反射了解集合泛型的本质
1 public class MethodDemo { 2 public static void main(String[] args) { 3 ArrayList arrayList = new ArrayList(); 4 ArrayList<String> arrayList1 = new ArrayList<String>(); 5 arrayList1.add("hello"); 6 Class c1 = arrayList.getClass(); 7 Class c2 = arrayList1.getClass(); 8 System.out.println(c1 == c2); // true 9 /* 反射的操作都是编译后的操作 */ 10 11 /* 12 * c1==c2返回true说明编译之后集合的泛型是去泛型化的 13 * Java中集合的泛型是防止错误输入的,只在编译阶段有效, 14 * 绕过编译就无效了 15 * 验证:可以通过方法的反射来操作,绕过编译 16 * */ 17 try { 18 Method m = c2.getMethod("add", Object.class); 19 m.invoke(arrayList1, 20); 20 System.out.println(arrayList1.size()); 21 System.out.println(arrayList1); 22 } catch (Exception e) { 23 e.printStackTrace(); 24 } 25 } 26 }