java:反射(Hibernate的雏形)
* java.lang.Class类:Class类的实例表示正在运行的 Java 应用程序中的类和接口,没有构造方法。
java反射机制是在运行状态中,对于任何一个类,都能够知道这个类的所有属性和方法,对于任意一个对象想,都能够调用他的任意一个方法和属性,这种动态获取的信息以及动态调用对象的方法的功能称为java的反射机制。
*
* 常用方法:
* forName(String className) 返回与带有给定字符串名的类或接口相关联的 Class 对象。
* Field[] getDeclaredFields()返回 Field对象的一个数组,这些对象反映此 Class 对象所表示的类或接口所声明的所有字段。
* Method[] getDeclaredMethods() 返回 Method对象的一个数组,这些对象反映此 Class 对象表示的类或接口声明的所有方法,
* 包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。(该类中的方法信息)
Constructor[] Constructor<?>[] getDeclaredConstructors()
返回 Constructor 对象的一个数组,这些对象反映此 Class 对象表示的类声明的所有构造方法。
* java.lang.reflect.Field类:Field 提供有关类或接口的单个字段的信息,以及对它的动态访问权限(获取属性的信息)
* 常用方法:
* getModifiers() 以整数形式返回由此 Field 对象表示的字段的 Java语言修饰符。
* 1:public 2:private 4:protected 0:默认
* getName()返回此 Field 对象表示的字段的名称。
* getType() 返回一个 Class 对象,它标识了此 Field 对象所表示字段的声明类型。
*
* java.lang.reflect.Method类:Method 提供关于类或接口上单独某个方法(以及如何访问该方法)的信息
* 常用方法:
* getModifiers() 以整数形式返回此 Method 对象所表示方法的 Java 语言修饰符。
* getReturnType()返回一个 Class 对象,该对象描述了此 Method 对象所表示的方法的正式返回类型。
* getName() 以 String 形式返回此 Method 对象表示的方法名称。
* getParameterTypes() 按照声明顺序返回 Class 对象的数组,这些对象描述了此 Method 对象所表示的方法的形参类型。
* getExceptionTypes() 返回 Class 对象的数组,这些对象描述了声明将此 Method 对象表示的底层方法抛出的异常类型。
*
* java.lang.reflect.Constructor类:
* 常用方法:
* getModifiers() 以整数形式返回此 Constructor 对象所表示构造方法的 Java 语言修饰符。
* getName() 以字符串形式返回此构造方法的名称。
* getParameterTypes()按照声明顺序返回一组 Class 对象,这些对象表示此 Constructor 对象所表示构造方法的形参类型。
public class Student { private String name; private int age; public Student(){ } public Student(String name,int age){ this.name=name; this.age=age; } public void intro(){ System.out.println("姓名:"+name); System.out.println("年齡:"+age); } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
public class TestClass { public static void main(String[] args) { // Student student = new Student(); // Class student = Student.class; try { Class clazz = Class.forName("cn.zzsxt.reflect1.Student"); System.out.println("------属性信息--------"); //获取该类中声明的属性(字段) Field[] fields = clazz.getDeclaredFields(); for (Field field : fields) { int modifier = field.getModifiers();//获取字段的修饰符 Class fieldType = field.getType();//获取字段数据类型 String fieldName = field.getName();//获取字段的名称 System.out.println(modifier+"----"+fieldType+"----"+fieldName); } System.out.println("--------方法信息---------"); Method[] methods = clazz.getDeclaredMethods(); for (Method method : methods) { int modifier = method.getModifiers();//获取方法的修饰符 Class returnType = method.getReturnType();//获取返回值类型 String methodName = method.getName();//获取方法名 Class[] paraTypes = method.getParameterTypes(); Class[] exceptionTypes = method.getExceptionTypes(); System.out.println(modifier+"---"+returnType+"---"+methodName+"---"+Arrays.toString(paraTypes)+"---"+Arrays.toString(exceptionTypes)); } System.out.println("----------构造方法-------------"); Constructor[] constructors = clazz.getDeclaredConstructors(); for (Constructor constructor : constructors) { int modifier = constructor.getModifiers(); String conName = constructor.getName(); Class[] conTypes= constructor.getParameterTypes(); System.out.println(modifier+"---"+conName+"---"+Arrays.toString(conTypes)); } } catch (ClassNotFoundException e) { e.printStackTrace(); } } }
* java.lang.reflect.Method类
* invoke(Object obj, Object... args)
* 对带有指定参数的指定对象调用由此 Method 对象表示的底层方法。(回调方法)
import java.lang.reflect.Field; /** * java.lang.Class类 * getDeclaredField(String name) 返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段 * * * java.lang.reflect.Field类:描述类或接口的字段信息 * getModifiers() 以整数形式返回由此 Field 对象表示的字段的 Java语言修饰符。 * 1:public 2:private 4:protected 0:默认 * getName()返回此 Field 对象表示的字段的名称。 * getType() 返回一个 Class 对象,它标识了此 Field 对象所表示字段的声明类型。 * set(Object obj, Object value)将指定对象变量上此 Field 对象表示的字段设置为指定的新值。 * get(Object obj) 返回指定对象上此 Field 表示的字段的值。 * * */ public class TestField { public static void main(String[] args) { try { Class clazz = Class.forName("cn.zzsxt.reflect1.Student");//动态加载类 Object obj = clazz.newInstance();//动态创建对象 Student student = new Student(); //获取name字段信息 Field field = clazz.getDeclaredField("name"); field.setAccessible(true); field.set(obj, "zhangsan");//为obj对象的name属性设置 Object value = field.get(obj); System.out.println(value); } catch (Exception e) { e.printStackTrace(); } } }
import java.lang.reflect.Method; /** * java.lang.reflect.Method类 * invoke(Object obj, Object... args) * 对带有指定参数的指定对象调用由此 Method 对象表示的底层方法。(回调方法) * */ public class TestMethod { public static void main(String[] args) { try { Class clazz = Class.forName("cn.zzsxt.reflect1.Student"); Object obj = clazz.newInstance();//动态创建对象Student student = new Student(); Method setName = clazz.getDeclaredMethod("setName", String.class);//获取setName方法 //student.setName("zhangsan"); //回调setter方法 setName.invoke(obj, "zhangsan");//第一个参数是对象,第二个参数是方法中实参 Method getName = clazz.getDeclaredMethod("getName", null);//获取getName方法 //回调getter方法 Object returnValue = getName.invoke(obj, null); System.out.println(returnValue); } catch (Exception e) { e.printStackTrace(); } } }
import java.lang.reflect.Constructor; /** *java.lang.reflect.Constructor类 * newInstance(Object... initargs) 使用此 Constructor 对象表示的构造方法来创建该构造方法的声明类的新实例,并用指定的初始化参数初始化该实例。 * */ public class TestConstractor { public static void main(String[] args) { try { Class clazz = Class.forName("cn.zzsxt.reflect1.Student"); //获取指定参数的构造方法 Constructor constructor = clazz.getDeclaredConstructor(String.class,int.class); Object obj = constructor.newInstance("zhangsan",20);//Student stu = new Student("zhangsan",20); System.out.println(obj); } catch (Exception e) { e.printStackTrace(); } } }
* Hibernate的雏形
* User user = new User(1,"zhangsan","123");
* Student student = new Student("lisi",20);
* save(user)
* ----> insert into User(userId,userName,password) values('1','zhangsan','123');
* save(student)
* ----> insert into Student(name,age) values('lisi','20');
public class User { private int userId; private String userName; private String password; public User(){ } public User(int userId,String userName,String password){ this.userId=userId; this.userName=userName; this.password=password; } public int getUserId() { return userId; } public void setUserId(int userId) { this.userId = userId; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
public class MyHibernate { public static void save(Object obj) throws Exception{ StringBuilder sb = new StringBuilder("insert into "); Class clazz = obj.getClass(); // String className = clazz.getName();//全类名(报名+类名) String className = clazz.getSimpleName();//获取简单类名(类名) sb.append(className+"(");//insert into User( //获取类的属性信息 Field[] fs = clazz.getDeclaredFields(); for (Field field : fs) { String fieldName = field.getName();//获取属性名称 sb.append(fieldName+","); }//insert into User(userId,userName,password, //将最后一个逗号替换成右括号insert into User(userId,userName,password) sb.replace(sb.lastIndexOf(","),sb.lastIndexOf(",")+1, ")"); sb.append(" values(");//insert into User(userId,userName,password) values( for (Field field : fs) { String fieldName = field.getName();//获取属性名称 //根据属性名称获取其对应的getter方法名 String getterMethodName = makeGetter(fieldName); //根据getter方法名称获取对应的getter方法 Method getterMethod = clazz.getDeclaredMethod(getterMethodName, null); //回调getter方法 Object value = getterMethod.invoke(obj, null); sb.append("'"+value+"',"); }//insert into User(userId,userName,password) values('1','zhangsan','123', //将最后一个逗号替换成右括号 sb.replace(sb.lastIndexOf(","),sb.lastIndexOf(",")+1, ")"); System.out.println(sb); } /** * 根据属性名称拼接其对应的getter方法:get+属性的首字母大写+其余字母 * @param fieldName:userId * @return getUserId */ public static String makeGetter(String fieldName){ return "get"+fieldName.substring(0,1).toUpperCase()+fieldName.substring(1); } public static void main(String[] args) { User user = new User(1,"zhangsan","123"); Student student = new Student("test",20); try { // save(user); save(student); } catch (Exception e) { e.printStackTrace(); } } }
* 解析配置文件web.xml,利用servlet-name节点中信息做键,servlet-class节点中的信息做值。
* <servlet>
<servlet-name>login</servlet-name>
<servlet-class>cn.zzsxt.reflect3.LoginServlet</servlet-class>
</servlet>
public interface Servlet { public void service(); }
public class LogoutServlet implements Servlet { @Override public void service() { System.out.println("执行用户退出功能!"); } }
public class LoginServlet implements Servlet{ public void service(){ System.out.println("处理登陆功能!"); } }
public class IndexServlet implements Servlet{ public void service(){ System.out.println("处理并展示首页功能!"); } }
public static Map<String,String> parseXML(String path){ Map<String,String> map = new HashMap<String,String>(); SAXReader saxReader = new SAXReader(); try { Document document = saxReader.read(path); //获取根节点信息 Element webapps = document.getRootElement(); Iterator<Element> servletIter = webapps.elementIterator(); while(servletIter.hasNext()){ Element servlet = servletIter.next(); Iterator<Element> servletSubIter = servlet.elementIterator(); String servletName=null; String servletClass=null; while(servletSubIter.hasNext()){ Element servletSub = servletSubIter.next(); String name = servletSub.getName(); if(name.equals("servlet-name")){ servletName = servletSub.getText();//获取servlet-name节点的文本 }else if(name.equals("servlet-class")){ servletClass = servletSub.getText();//获取servlet-class节点的文本 } //添加到map中 } map.put(servletName, servletClass); } } catch (DocumentException e) { e.printStackTrace(); } return map; } public static void main(String[] args) { Map<String,String> map = parseXML("web.xml"); System.out.println(map); } }
/** * 问题:每增加一个servlet就需要添加判断,程序的扩展性比较差,违背了"开闭原则"。 * * */ public class Test { public static void main(String[] args) { //解析配置文件:web.xml Map<String,String> map = XMLUtils.parseXML("web.xml"); Scanner input = new Scanner(System.in); System.out.println("请输入servlet的名称:"); String servletName = input.next(); // if("login".equals(servletName)){ // LoginServlet loginServlet = new LoginServlet(); // loginServlet.service(); // }else if("index".equals(servletName)){ // IndexServlet indexServlet = new IndexServlet(); // indexServlet.service(); // } //根据用户输入的名称查找该Servlet的全类名 String servletClass = map.get(servletName); //动态创建servlet对象 try { Servlet servlet = (Servlet)Class.forName(servletClass).newInstance(); servlet.service();//多态 } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }