java 从零开始,学习笔记之基础入门<反射>(二十九)

时间:2021-12-24 19:39:30

反射

什么是反射?反射的作用

反射是利用类的加载机制,对类进行动态操作的一种体现,操作类的成员属性和方法(一般都是公共的)。

反射的作用:在现在的J2EE应用领域中所使用的较多,一般都采用反射来对“类和表的映射文件”进行动态解析并实例化的操作,常见于ORM映射技术中。有时也在一些轻量级容器中能见到此技术的应用,比如Spring。总之,J2EE中一般都能见到此技术的运用。普通的反射效率较低,但可操作性较强,有时候也配合动态代理技术来完成相关运用。

 

实例化步骤

1.      调用Class中的forName()方法根据类名实例化一个Object类型的对象

2.      强制转化成所需类型

 

 

利用反射的知识拼装sql语句

原来在DAO中的操作如下:

Insert into usertb valuse(user.getName,user.getPwd)

 

改成反射动态拼装,如何做?

已知条件:已赋值的对象

 

见到“class...”说明此处的参数是类型数组,如果见到“object…”说明此处的参数是对象数组

 

利用反射的一些例子

反射的方法

SoftDevoloper.java

SoftDevoloper.java

package com.ibm.dto;

 

public class SoftDevoloper {

/**

 * 软件工程师  

 * @param devId

 * @param devName

 * @param age

 */

   

    public SoftDevoloper(int devId,String devName,int age){

       this.devId=devId;

       this.devName=devName;

       this.age=age;

    }

   

    public SoftDevoloper(){

      

    }

   

    //编号

    privateint devId;

    //名称

    private StringdevName;

    //年龄

    privateint age;

    //技能

    private String[]skill;

   

   

    publicint getDevId() {

       returndevId;

    }

    publicvoid setDevId(int devId) {

       this.devId = devId;

    }

    public String getDevName() {

       return devName;

    }

    public void setDevName(String devName) {

       this.devName = devName;

    }

    publicint getAge() {

       returnage;

    }

    public void setAge(int age) {

       this.age = age;

    }

 

    public String[] getSkill() {

       returnskill;

    }

 

    public void setSkill(String[] skill) {

       this.skill = skill;

    }

   

     

}

 

 

ArgDemo.java


package com.ibm.test;

 

/**

 * 反射中方法多个参数的调用类

 * @author Administrator

 *

 */

public class ArgDemo {

   

    /**

     * 说话

     * @param uname用户

     * @param msg说的内容

     * @param len说的长度

     */

    public void say(String uname,String msg,int len){

      

       System.out.println(uname+""+msg+"一共"+len+"个长度");

    }

 

}

 

 

Test.java

Test.java

  package com.ibm.test;

 

 

import java.lang.reflect.Constructor;

import java.lang.reflect.Field;

import java.lang.reflect.InvocationTargetException;

import java.lang.reflect.Method;

 

import com.ibm.dto.SoftDevoloper;

 

 

public class Test {

   

    publicvoid GetInstance()

    {

      

           //生成一个开发人员的实例对象

           Object obj;

           try {

              obj = Class.forName("com.ibm.dto.SoftDevoloper").newInstance();

              //强制转换成所需类型

              SoftDevoloper sdl=(SoftDevoloper)obj;

              sdl.setDevName("詹姆斯");

              System.out.println(sdl.getDevName());

             

           } catch (ClassNotFoundException e) {

              //TODO Auto-generated catch block

              e.printStackTrace();

           } catch (InstantiationException e) {

              //TODO Auto-generated catch block

              e.printStackTrace();

           } catch (IllegalAccessException e) {

              //TODO Auto-generated catch block

              e.printStackTrace();

           }

    }

    /**

     * 测试获取类中的方法

     * @param args

     */

    publicvoid testMethod()

    {

       try {

           //根据类名找到对象

           Class sodCls=Class.forName("com.ibm.dto.SoftDevoloper");

          //返回方法数组

           Method[] method=sodCls.getDeclaredMethods();

         //循环操作方法

           for (Method method2 : method) {

           System.out.println("方法名是:"+method2.getName());

          

       }

       } catch (ClassNotFoundException e) {

           e.printStackTrace();

       }

    }

   

    /**

     * 操作属性

     */

    public void testField(){

      

       Class sodCls;

       try {

           sodCls = Class.forName("com.ibm.dto.SoftDevoloper");

      

       Field[] field=sodCls.getDeclaredFields();

      

       for(Field field2:field){

           System.out.println("属性名:"+field2.getName());

       }

      

       } catch (ClassNotFoundException e) {

           e.printStackTrace();

       }     

    }

   

    /**

     * 类中构造器

     * @param args

     */

    publicvoid testConst(){

   

       Class sodCls;

       try {

           sodCls = Class.forName("com.ibm.dto.SoftDevoloper");

           Constructor[] constr=sodCls.getConstructors();

          

           for(Constructor constructor:constr){

              System.out.println("构造器:"+constructor.getName());

           }

       } catch (ClassNotFoundException e) {

           e.printStackTrace();

       }

      

    }

   

   

    /**

     * 方法的操作

     */

    publicvoid methodOperDemo(){

      

       SoftDevoloper sd=null;  

       Class cls=null;

       Method method=null;

       try {

           //实例化

           sd = new SoftDevoloper(1,"java", 18);

           //根据类名实例化类对象

           cls = Class.forName("com.ibm.dto.SoftDevoloper");

           //找到get方法

           method=cls.getMethod("getDevName");

           //调用invoke方法获得返回值

          Object retVal = method.invoke(sd,null);  

           System.out.println("返回值是:"+retVal);

          

       } catch (ClassNotFoundException e) {

           e.printStackTrace();

       } catch (SecurityException e) {

           e.printStackTrace();

       } catch (NoSuchMethodException e) {

           e.printStackTrace();

       } catch (IllegalArgumentException e) {

           e.printStackTrace();

       } catch (IllegalAccessException e) {

           e.printStackTrace();

       } catch (InvocationTargetException e) {

           e.printStackTrace();

       }

      

    }

   

    /**

     * 采用反射动态赋值

     * @param from原对象

     * @param to目标对象

     * @throws NoSuchMethodException

     * @throws SecurityException

     * @throws InvocationTargetException

     * @throws IllegalAccessException

     * @throws IllegalArgumentException

     */

    public void copy(Object from,Object to)throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException{

      

       Class fromCls=from.getClass();

      

       Class toCls=to.getClass();

      

       Field[] field=fromCls.getDeclaredFields();

      

       for(Field field2:field){

           //所有属性名

           String fieldName=field2.getName();

           //get方法

           String getMethodName="get"+fieldName.substring(0,1).toUpperCase()+fieldName.substring(1);

           //set方法

           String setMethodName="set"+fieldName.substring(0,1).toUpperCase()+fieldName.substring(1);

           //根据方法名找到具体的方法

           Method method=fromCls.getMethod(getMethodName,null);

          

           //获得get方法所返回的值

           Object objValue=method.invoke(from,null);

          

           //返回值类型根据返回值类型来确定set方法中参数的类型

           Class clsType=method.getReturnType();

          

           Method setMethod=toCls.getMethod(setMethodName, clsType);

          

           //将从from对象中取到值给to对象

           setMethod.invoke(to, objValue);

       }  

    }

   

   

(此处调用的是ArgDemo类)

    /**

     * 测试根据名称、参数来找方法

     */

    public void testArg(){  

       try {

           Class cls=Class.forName("com.ibm.test.ArgDemo");

          

           Object obj=cls.newInstance();

          

           String methodName="say";

           //找到方法

           Method method=cls.getDeclaredMethod(methodName,new Class[]{String.class,String.class,int.class});

          

           //调用方法并依次赋参数

           method.invoke(obj, new Object[]{"犀利哥","今年我要上春晚",7});

       } catch (ClassNotFoundException e) {

           e.printStackTrace();

       } catch (SecurityException e) {

           //TODO Auto-generated catch block

           e.printStackTrace();

       } catch (NoSuchMethodException e) {

           //TODO Auto-generated catch block

           e.printStackTrace();

       } catch (InstantiationException e) {

           //TODO Auto-generated catch block

           e.printStackTrace();

       } catch (IllegalAccessException e) {

           //TODO Auto-generated catch block

           e.printStackTrace();

       } catch (IllegalArgumentException e) {

           //TODO Auto-generated catch block

           e.printStackTrace();

       } catch (InvocationTargetException e) {

           //TODO Auto-generated catch block

           e.printStackTrace();

       }

      

    }

   

   

    public staticvoid main(String[] args) {

       Test test = new Test();

        test.GetInstance();

        test.testMethod();

        test.testField();

      

       test.testConst();

      

       test.methodOperDemo();

      

       SoftDevoloper sd1=new SoftDevoloper();

       sd1.setDevName("bill");

       sd1.setDevId(123);

       sd1.setAge(10);

      

       SoftDevoloper sd2 = new SoftDevoloper();

       //将值从sd1复制到sd2

       try {

           test.copy(sd1, sd2);

       } catch (SecurityException e) {

           //TODO Auto-generated catch block

           e.printStackTrace();

       } catch (IllegalArgumentException e) {

           //TODO Auto-generated catch block

           e.printStackTrace();

       } catch (NoSuchMethodException e) {

           //TODO Auto-generated catch block

           e.printStackTrace();

       } catch (IllegalAccessException e) {

           //TODO Auto-generated catch block

           e.printStackTrace();

       } catch (InvocationTargetException e) {

           //TODO Auto-generated catch block

           e.printStackTrace();

       }

       //获得sd2对象中的值

       System.out.println(sd2.getDevName());

       System.out.println(sd2.getDevId());

       System.out.println(sd2.getAge());

      

      

       test.testArg();

       }

   

   

}

 

 

 

利用反射实现对输入框获取到的值进行输出

FormToDtoUtil.java

FormToDtoUtil.java

package com.ibm.util;

 

import java.lang.reflect.InvocationTargetException;

import java.lang.reflect.Method;

import java.sql.Date;

import java.text.ParseException;

import java.text.SimpleDateFormat;

import java.util.Enumeration;

 

import javax.servlet.http.HttpServletRequest;

 

public class FormToDtoUtil {

   

/**

 * request对象中的值传递到DTO对象中

 * @param request请求对象

 * @param to赋值对象

 * @throws NoSuchFieldException

 * @throws SecurityException

 * @throws NoSuchMethodException

 * @throws ParseException

 * @throws InvocationTargetException

 * @throws IllegalAccessException

 * @throws IllegalArgumentException

 */

 

    publicvoid load(HttpServletRequest request ,Object to)throws SecurityException, NoSuchFieldException, NoSuchMethodException, ParseException, IllegalArgumentException, IllegalAccessException, InvocationTargetException{

      

       //getPatameterNames表示获得表单中控件的名称集合

       //枚举对象和迭代性质一样

       Enumeration  enumera=request.getParameterNames();

       //获得to对象的类实例

       Class toCls=to.getClass();

      

       while (enumera.hasMoreElements()) {

           String elem = (String) enumera.nextElement();

           System.out.println("控件名是:"+elem);

            String[] value=request.getParameterValues(elem);

           

            if(value!=null){

            //获得属性类型

            Class type=toCls.getDeclaredField(elem).getType();

            //获得属性对应的set方法 因为控件名是和dto中的属性是一致的,所以可以直接使用控件名来代替属性名

            String setMethodName="set"+elem.substring(0,1).toUpperCase()+elem.substring(1);          

            System.out.println("set的名字是:"+setMethodName);

            //根据方法名称找到set方法

            Method method=toCls.getDeclaredMethod(setMethodName, type);

           

            Object[] obj=objectConvert(value, type);

           

            //如果遇到数组类型

            if(type.isArray()){

                //遇到的类型是数组类型 则直接将数组赋值给to对象

                method.invoke(to,new Object[]{obj});

            }else{

                //非数组类型则  按照数组索引格式取出值,然后赋值即可

                method.invoke(to, new Object[]{obj[0]});

            }

           

       }

    }

      

    }

   

   

    /**

     * 数据转换方法因为dto中的属性类型不确定,只能针对所有需要的类型进行判断才能返回

     * 所需要的类型

     * @param value表单中所获取的值

     * @param FieldType DTO中字段的类型

     * @return返回对象默认以对象数组的格式返回

     * @throws ParseException

     */

   

    publicstatic Object[] objectConvert(String[] value,Class FieldType)throws ParseException{

      

       Object[] obj=new Object[value.length];

      

       if(FieldType==Integer.class||FieldType==int.class){

           obj[0]=Integer.parseInt(value[0]);

       }elseif(FieldType==Date.class){

           SimpleDateFormat format =new SimpleDateFormat("yyyy-MM-dd");

           obj[0]=format.parse(value[0]);

       }else{

           obj=value;

       }

       return obj;

    }

   

   

   

   

}

 

 

RegAction.java

RegAction.java

package com.ibm.action;

 

import java.io.IOException;

import java.io.PrintWriter;

import java.lang.reflect.InvocationTargetException;

import java.text.ParseException;

importjava.text.Normalizer.Form;

importjava.util.Enumeration;

 

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

 

import com.ibm.dto.SoftDevoloper;

import com.ibm.util.FormToDtoUtil;

 

public classRegAction extends HttpServlet {

 

    /**

     * Constructor of the object.

     */

    public RegAction() {

       super();

    }

 

    /**

     * Destruction of the servlet.<br>

     */

    publicvoid destroy() {

       super.destroy();// Just puts "destroy" string in log

       // Put your code here

    }

 

    /**

     * The doGet method of theservlet. <br>

     *

     * This method is called when a form has its tag value method equals to get.

     *

     * @param request the request send by the client to the server

     * @param response the response send by the server to the client

     * @throws ServletException if an error occurred

     * @throws IOException if an error occurred

     */

    publicvoid doGet(HttpServletRequest request, HttpServletResponse response)

           throws ServletException, IOException {

 

       response.setContentType("text/html");

       PrintWriter out = response.getWriter();

       out

              .println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");

       out.println("<HTML>");

       out.println(<HEAD><TITLE>A Servlet</TITLE></HEAD>");

       out.println(<BODY>");

       out.print("   This is ");

       out.print(this.getClass());

       out.println(", using the GET method");

       out.println(</BODY>");

       out.println("</HTML>");

       out.flush();

       out.close();

    }

 

    /**

     * The doPost method of theservlet. <br>

     *

     * This method is called when a form has its tag value method equals to post.

     *

     * @param request the request send by the client to the server

     * @param response the response send by the server to the client

     * @throws ServletException if an error occurred

     * @throws IOException if an error occurred

     */

    public void doPost(HttpServletRequest request, HttpServletResponse response)

           throws ServletException, IOException {

          

           //实例化开发人员对象未赋值

            SoftDevoloper sd= new SoftDevoloper();

            //动态赋值

            FormToDtoUtil ftd= new FormToDtoUtil();

           

            try {

              ftd.load(request, sd);

             

              System.out.println("获得的值是:"+sd.getDevName());

             

           } catch (SecurityException e) {

              //TODO Auto-generated catch block

              e.printStackTrace();

           } catch (IllegalArgumentException e) {

              //TODO Auto-generated catch block

              e.printStackTrace();

           } catch (NoSuchFieldException e) {

              //TODO Auto-generated catch block

              e.printStackTrace();

           } catch (NoSuchMethodException e) {

              //TODO Auto-generated catch block

              e.printStackTrace();

           } catch (ParseException e) {

              //TODO Auto-generated catch block

              e.printStackTrace();

           } catch (IllegalAccessException e) {

              //TODO Auto-generated catch block

              e.printStackTrace();

           } catch (InvocationTargetException e) {

              //TODO Auto-generated catch block

              e.printStackTrace();

           }

          

    }

   

   

   

 

    /**

     * Initialization of the servlet. <br>

     *

     * @throws ServletException if an error occurs

     */

    publicvoid init()throws ServletException {

       // Put your code here

    }

 

}