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();
        } 
        
    }
}

 

posted @ 2017-06-23 12:25  咫尺天涯是路人丶  阅读(190)  评论(0编辑  收藏  举报