反射

来源:互联网 发布:微信模板消息 java 编辑:程序博客网 时间:2024/05/18 21:10

反射:

程序在运行的时候识别类(接口)的能力,在运行的过程中可以读取元数据。

关于反射的我们一共要知道5个类:

Java.lang.class;

Java.lang.reflect.Constructor;

Java.lang.reflect.Field;

Java.lang.reflect.Method;

Java.lang.reflect.Modifier;

下面我们一个个来说:

Class:

就是用来当反射的入口,用来创建类实例。

public static void equals(Object obj,Object obj1){        Class<?> c=obj.getClass();    Class<?> c1=obj1.getClass();//getclass()object的,用来返回运行时的类。        if(c==c1){            System.out.println("相等的两个"+c.getSimpleName());        }else{            System.out.println("是不相等的");            System.out.println("其中一个是:"+c.getSimpleName()+"另外一个是:"+c1.getSimpleName());        }}

 

getName(),getSimpleName();getSuperClass();getModifiers()时常用的方法。

Class中更为常用的是下面的几组:

Field[] getDeclaredFields();

FieldgetDeclaredField(String);

Field[]getFields();

FieldgetField(String);这四种方法用来获取Field;

ConstructorgetConstructor(Class…c);

Constructor[]getConstructors();

ConstructorgetDeclaredConstructor();

Constructor[]getDeclaredConstructors();这四种方法用来获取Constructor;

 

Method getMethod (Stringname,Class<?>…args);

Method [] getMethods();

Method getDeclaredMethod(String name,Class<?>…args);

Method []getDeclaredMethods()这四种方法用来获取Method;

 

这些都是在class中的方法,带有Declared的和不带的区别就在于,带的可以访问private的属性,不带的不行;

Field类:

Field代表一个属性,Field中包括属性名,数据类型,修饰符。

因为这个类可以让我们获得到vo中的所有属性,而属性我们设置的就是mysql数据库中的表中的列名,vo的文件名就是数据库的表名,所以我们可以用Field来拼一个sql语句,动态的进行操作数据库。

public static voidinsert(Object obj){
    Class<?> c=obj.getClass();
    StringBuffer sql=new StringBuffer("insert into "+c.getSimpleName()+"(");
    StringBuffer sql1=new StringBuffer(")values(");
    Field[] fs=c.getDeclaredFields();
    for(inti=0;i<fs.length;i++){
        if(i!=fs.length-1){
            sql.append(fs[i].getName()+",");
            sql1.append("?,");
        }else{
            sql.append(fs[i].getName());
            sql1.append("?);");
        }

    }
    sql.append(sql1);
    System.out.println(sql);
}

 

Field常用的方法:getName();getType();getModifiers();

Field因为他的这些方法就可以对属性进行读和写的操作了,对象的属性,值的操作。

用:Object get(Object obj);

     Voidset(Object obj,Object value);

来来来再看个简单的栗子,代码里面加上了之前的东西哦….

public static void save(Object obj) throws SQLException {    Class<?> c=obj.getClass();    StringBuffer sql=new StringBuffer("insert into "+c.getSimpleName()+"(");    StringBuffer sql1=new StringBuffer(")values(");    Field[] fs=c.getDeclaredFields();    for(int i=0;i<fs.length;i++){        if(i!=fs.length-1){            sql.append(fs[i].getName()+",");            sql1.append("?,");        }else{            sql.append(fs[i].getName());            sql1.append("?);");        }    }    sql.append(sql1);    Connection conn= DriverManager.getConnection("jdbc:mysql://localhost:3306/java1025?Unicode=true&characterEncoding=UTF-8","root","");    PreparedStatement ps=null;    try{        ps=conn.prepareStatement(sql.toString());        for(int i=0;i<fs.length;i++){            fs[i].setAccessible(true);
ps.setObject(i+1,fs[i].get(obj));        }        ps.execute();        System.out.println("插入成功");    }catch(Exception e){        e.printStackTrace();    }finally{        ps.close();        conn.close();    }}
(原谅我抛出异常没处理,自己写处理一下吧,不往外面抛出)
上面有一段代码是:setAccessible,设置属性的可访问性的,如果不设置的话,有些private的无法访问。
上课的时候同学问了我一个问题,我觉得good呀,确实是没区分清的孩纸容易疑问,问题如下:在有Declared的方法里面老师说这个是用来获取全部的,那setAccessible方法又是让你获取全部的,这不重复了吗?当然不,有Declared的是可以用来获取私有的Field,Constructor,Method的,而setAccessible是设置你获取完的东西里面的私有的可以访问,就是你要用Declared这个房卡进门,你才能进行后续的操作吖…..

Constructor类:

代表一个类中的构造方法,这个类中封装定义了构造方法;

常用的方法:getName(),getModifiers(),getParameterTypes();newInstance()

Method类:

提供了关于类或接口上的单独的某个方法的信息,代表类中的一个方法的定义,一个method由修饰符,返回值类型,方法名称,参数列表组成;

Method提供的方法有:

getName():获得方法名;

getModifiers():获得修饰符;

getReturnType():返回值类型;

getParameterTypes():参数类型的数组;

invoke(Objectobj,Object…args);方法被调用

public  static <T> List<T> getAll(Class<T> c) throws SQLException {    String sql="select * from "+c.getSimpleName(); Connection conn= DriverManager.getConnection("jdbc:mysql://localhost:3306/java1025?Unicode=true&characterEncoding=UTF-8","root",""); PreparedStatement ps=null; Field[] fs=c.getDeclaredFields(); List<T> list=new ArrayList<T>();    ResultSet rs=null;    try{        ps=conn.prepareStatement(sql);        rs=ps.executeQuery();        while(rs.next()){            T obj=c.newInstance();            for(Field f:fs){                f.setAccessible(true);                f.set(obj,rs.getObject(f.getName()));            }            list.add(obj);        }    }catch(Exception e){        e.printStackTrace();    }    return list;}