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

原创 2013年12月04日 10:10:15

反射

什么是反射?反射的作用

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

反射的作用:在现在的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(){

      

    }

   

    //编号

    private int devId;

    //名称

    private String devName;

    //年龄

    private int age;

    //技能

    private String[] skill;

   

   

    public int getDevId() {

       return devId;

    }

    public void setDevId(int devId) {

       this.devId = devId;

    }

    public String getDevName() {

       return devName;

    }

    public void setDevName(String devName) {

       this.devName = devName;

    }

    public int getAge() {

       return age;

    }

    public void setAge(int age) {

       this.age = age;

    }

 

    public String[] getSkill() {

       return skill;

    }

 

    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 {

   

    public void 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

     */

    public void 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

     */

    public void 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();

       }

      

    }

   

   

    /**

     * 方法的操作

     */

    public void 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 static void 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

 */

 

    public void 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

     */

   

    public static 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;

import java.text.Normalizer.Form;

import java.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 class RegAction extends HttpServlet {

 

    /**

     * Constructor of the object.

     */

    public RegAction() {

       super();

    }

 

    /**

     * Destruction of the servlet. <br>

     */

    public void destroy() {

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

       // Put your code here

    }

 

    /**

     * The doGet method of the servlet. <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

     */

    public void 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 the servlet. <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

     */

    public void init() throws ServletException {

       // Put your code here

    }

 

}

 

 

相关文章推荐

java 从零开始,学习笔记之基础入门<Struts2_实战演练(下)>(四十)

Struts2_实战演练(下) 国际化 1.        导入相关的包 2.        配置国际化资源文件:gobalMessage_en_US.properties(src目录下,1.前...
  • lulu147
  • lulu147
  • 2014年02月18日 12:41
  • 1385

java 从零开始,学习笔记之基础入门<Struts2_Spring_整合>(四十一)

Struts-Spring Struts-Spring整合配置图   Spring配置文件 applicationContext.xml xml ...
  • lulu147
  • lulu147
  • 2014年02月19日 09:43
  • 1019

java 从零开始,学习笔记之基础入门<Oracle_查询>(三十四)

Oracle多表查询 --部门 create table dept_tb( dept_id number(3) primarykey, dept_no varchar...
  • lulu147
  • lulu147
  • 2013年12月16日 14:15
  • 948

java 从零开始,学习笔记之基础入门<正则表达式>(三十一)

正则表达式 JAVA中正则表达式: ² [a-z]表示字母a到z任意一个字符 ² [A-Z]表示A到Z任意一个字符 ² [0-9]表示数字0到9中任意一个数字 ² //"^"表示以某个字符开...
  • lulu147
  • lulu147
  • 2013年12月06日 10:21
  • 1620

java 从零开始,学习笔记之基础入门<DOM解析>(三十二)

DOM解析   DOM解析一 基础知识 TestXMLParseDemo package com.ibm.xmldemo;   import java.io.File; import ...
  • lulu147
  • lulu147
  • 2013年12月10日 10:29
  • 1289

java 从零开始,学习笔记之基础入门<重载_覆盖_继承>(十)

重载_覆盖_继承 方法的覆盖(重写) 子类继承父类的时候,父类里面的方法都被子类所继承(除了私有的方法),如果父类里面的方法不能够满足子类的需求,那么就必须在子类里面对父类的方法进行覆盖,覆盖的同...
  • lulu147
  • lulu147
  • 2013年11月06日 09:53
  • 683

java 从零开始,学习笔记之基础入门<对象_属性>(二)

2_4_对象_属性 第一个小程序:  publicclass Hello{  public static void main(String args[]){  System.out.println("...
  • lulu147
  • lulu147
  • 2013年10月25日 17:35
  • 1030

java 从零开始,学习笔记之基础入门<类_方法_构造器>(三)

(三)类_方法_构造器 *类的命名 *类名必须与源文件名保持一致,并且英文之间不能有空格。 *类名首字母不能为数字,首字母可以为_和$。 *类名不能为关键字。 *类名如果包含多个单词,那么首字母一般都...
  • lulu147
  • lulu147
  • 2013年10月28日 11:57
  • 1154

java 从零开始,学习笔记之基础入门<数组列表(ArrayList)>(九)

数组列表(ArrayList) 数组列表(ArrayList)     是用来存储可变容量的数组,创建一个ArrayList对象默认的大小为10,如果我们往这个容器中放值,放入值的个数如果超过了默...
  • lulu147
  • lulu147
  • 2013年11月05日 09:47
  • 1322

java 从零开始,学习笔记之基础入门<数据库连接配置>(二十八)

数据库连接配置 配置方式一: 1.        在tomcat中输入地址http://localhost:8080/admin进入管理控制台,找到service节点中的host节点,在此节点中查...
  • lulu147
  • lulu147
  • 2013年12月03日 16:16
  • 1293
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:java 从零开始,学习笔记之基础入门<反射>(二十九)
举报原因:
原因补充:

(最多只允许输入30个字)