javaSE 反射(掌握理解) 分析

## 反射知识##

  1. 什么是反射: 按照类的生命周期,先编译生成 .class(字节码)对象,然后JVM类加载器去加载 class对象,解析,实例化等一系列,然后 给调用者使用。 然而反射这一技术 是怎么体现: 通过字节码文件对象,去使用成员变量,构造方法,成员方法;大概就是 以前这些操作 要new xx();现在只要 class对象,就可以去操作;大概就是 反过来使用。

    现在 提基本语法,然后等下再深入:
    A:通过反射获取构造方法并使用
    B:通过反射获取成员变量并使用
    C:通过反射获取成员方法并使用


        // ********A:通过反射获取构造方法并使用 ********

         // 获取字节码对象
        Class c = Class.forName("com.csmz.Person");
        // 获取带参构造方法对象
        // public Constructor<T> getConstructor(Class<?>... parameterTypes)
        Constructor con = c.getConstructor(String.class, int.class,
                String.class);

        // 通过带参构造方法对象创建对象
        // public T newInstance(Object... initargs)
            Object obj = con.newInstance("林青霞", 27, "北京");
        // 获取所有的成员变量
        // Field[] fields = c.getFields();
        // Field[] fields = c.getDeclaredFields();
        // for (Field field : fields) {
        // System.out.println(field);
        // }

         // ********B:通过反射获取成员变量并使用 ********

         /*
         * Person p = new Person(); p.address = "北京"; System.out.println(p);
         */

        // 通过无参构造方法创建对象
        Constructor con = c.getConstructor();
        Object obj = con.newInstance();
        System.out.println(obj);

        // 获取单个的成员变量
        // 获取address并对其赋值
        Field addressField = c.getField("address");
        // public void set(Object obj,Object value)
        // 将指定对象变量上此 Field 对象表示的字段设置为指定的新值。
        addressField.set(obj, "北京"); // 给obj对象的addressField字段设置值为"北京"
        System.out.println(obj);

         // ********C:通过反射获取成员方法并使用 ********

         // 获取单个方法并使用
        // public void show()
        // public Method getMethod(String name,Class<?>... parameterTypes)
        // 第一个参数表示的方法名,第二个参数表示的是方法的参数的class类型
         Method m1 = c.getMethod("show");
        // obj.m1(); // 错误
        // public Object invoke(Object obj,Object... args)
        // 返回值是Object接收,第一个参数表示对象是谁,第二参数表示调用该方法的实际参数
        m1.invoke(obj); // 调用obj对象的m1方法

2. 基本 语法 就是这样了,但是 好多初学者 虽然知道知识点,但是不知道怎么去理解运用!
我现在 知识点水平到了 SSH 左右了,我来描述下,我在 学知识途中 怎么去理解运用:
– 在学 Servlet时 from 表单传递请求参数,我们要进行封装,

  • -解决一:servlet 我可以getPartmert(“xx”); 然后bean.setXX()这样去封装,假如参数传递过来参数多了,我们这样 去获取 不是很麻烦,于是我采取了方式二:利用反射知识点去解决.

    -解决二: 利用反射知识点 但是表单的传递过来的name 必须先和bean的属性名相同,试着去写,真的好方便 ,我以前的代码:

    <form action="/day_01Servlet/servlet2/MyServlet2" method="post">

    姓名:<input id="name" type="text" name="name"/><br/>
    密码:<input type="password" name="password"/><br/>
    性别:<input type="radio" name="gender" value="1" checked="checked"/>男
    <input type="radio" name="gender" value="0"/>女<br/>
    <!-- 建议不写(选中true   不选false)    value属性:  true,on,1  -->

已婚:<input type="checkbox" name="married" value="true" /><br/>
    故乡:<select name="city">
    <option value="BJ">北京</option>
    <option value="SD">山东</option>
    <option value="HB">湖北</option>
    </select><br/>
    爱好:<input type="checkbox" name="hobby" value="eat"/>吃饭
    <input type="checkbox" name="hobby" value="sleep"/>睡觉
    <input type="checkbox" name="hobby" value="java"/>学Java<br/>
    简介:<textarea name="description" rows="3" cols="38"></textarea><br/><input type="submit" value="注册"/>

</form>
    /**
     * 使用反射知识点,获取 请求参数,然后封装Bean author:renfuyi
     * 
     * @throws IllegalAccessException
     * @throws IllegalArgumentException
     * 
     */
    public Object getBean(HttpServletRequest request,
            HttpServletResponse response) throws IllegalArgumentException,
            IllegalAccessException {
        // 获得实体
        Student student = new Student();
        // 获取 请求参数
        Enumeration<String> enumeration = request.getAttributeNames();
        // 获得实体 字节码对象
        Class stu_class = student.getClass();
        // 获得 成员方法
        Field[] fields = stu_class.getDeclaredFields();
        int i = 0;
        while (enumeration.hasMoreElements()) {
            // 成员变量对象 进行赋值
            fields[0].set(student,
                    request.getAttribute(enumeration.nextElement()));
            i++;
        }
        return student;
    }

正因为 用反射,方便,伟大先辈们 ,已经跟我们封装好了 BeanUtils.JAR,上面代码也就是 BeanUtils底层。

 /**
      * 使用Beanutils
     * @throws Exception 
     * @throws IllegalAccessException 
      */
     private void testParamter03(HttpServletRequest request) throws IllegalAccessException, Exception{
         Student student=new Student(); 
         System.out.println("封装前"+student); 
         BeanUtils.populate(student,request.getParameterMap());
          System.out.println("封装后"+student);

     }

– 在配置spring 时,直接写上类的全路径比如 (”com.mchange.v2.c3p0.ComboPooledDataSource”)
  该spring框架,就通过你配置的路径,用Class.forName(“全路径”),然后.newIntance(),跟你new 出来,假如修改 你只需要修改配置文件 就OK了.

<bean id="ds" class="com.mchange.v2.c3p0.ComboPooledDataSource">

项目练习:我用到反射+泛型知识点,去描述 通用类(父类),确实方便多了,然后 灵活应用也体现了。


public class UserDaoImpl extends BaseDaoImpl<User> implements IUserDao 
public class RegionDaoImpl extends BaseDaoImpl<region> implements IRegionDao
**
 * 持久层通用实现
 * 
 * @author renfuyi
 * 
 * @param <T>
 */
public class BaseDaoImpl<T> extends HibernateDaoSupport implements IBaseDao<T> {

    // T 的 实体 class对象
    private Class<T> entityClass;

    @Resource
    public void setMySessionFactory(SessionFactory sessionFactory) {
        super.setSessionFactory(sessionFactory);
    }

    /**
     * 构造方法中 获得 T 这个class 对象
     */
    public BaseDaoImpl() {
        // 1.0 获得 父类的泛型 对象
        ParameterizedType type = (ParameterizedType) this.getClass()
                .getGenericSuperclass();
        // 2.0 获得泛型对象
        Type[] types = type.getActualTypeArguments();
        entityClass = (Class<T>) types[0];
    }

    @Override
    public void save(T entity) {
        this.getHibernateTemplate().save(entity);
    }

    @Override
    public void delete(T entity) {
        this.getHibernateTemplate().delete(entity);
    }

大概总结:虽然懂了 反射知识点,但是 得去灵活运用,慢慢 去体会 其中的奥秘,我也希望 java初学者,学的知识 要去拓展。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值