反射

作者: 尉昌达 | 来源:发表于2020-06-28 22:35 被阅读0次
package com.ycd.reflect;
public class Person {
    public String name;
    public int age;

    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String show(){
        return "name:"+name+", age :"+age;
    }
}
package com.ycd.reflect;
public class Student extends Person{
    public String className;
    private String address;

    public Student(){
        super();
    }

    private Student(String name,int age,String className){
        super(name,age);
        this.className= className;
    }
    public Student(String name,int age,String className,String address){
        super(name,age);
        this.className = className;
        this.address = address;
    }

    public String getClassName() {
        return className;
    }

    public void setClassName(String className) {
        this.className = className;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    private void add(int a,int b){
        System.out.println(a+b);
    }

    @Override
    public String toString() {
        return "Student{" +
                "className='" + className + '\'' +
                ", address='" + address + '\'' +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
public class ClassAPI {
    public static void main(String[] args) throws Exception{
        Class<?> clazz = Class.forName("com.ycd.reflect.Student");
        //获取成员变量,包括子类及父类,同时只能包含公共的方法
        Field[] fields = clazz.getFields();
        for (Field field : fields) {
            System.out.println(field);
            System.out.println(field.getName());
            System.out.println(field.getType());
            System.out.println(field.getModifiers());
            System.out.println("-----");
        }
        System.out.println("1=======================1");

        //此方法返回的是当前类的所有属性,不仅仅局限于公共访问修饰符,所有的访问修饰符都可以拿到
        Field[] declaredFields = clazz.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println(declaredField.getName());
        }
        System.out.println("2========================2");

        //反射在一定程度上破坏了封装性,需要合理使用
        Field address = clazz.getDeclaredField("address");
        //设置该属性是否能被访问,true表示能被访问,破坏了封装性
        address.setAccessible(true);
        System.out.println(address.getName());
        Object o = clazz.newInstance();
        address.set(o,"北京市");
        System.out.println(((Student)o).getAddress());
        System.out.println("3========================3");

        //获取该对象的普通方法,包含的方法范围是当前对象及父类对象的所有公共方法
        Method[] methods = clazz.getMethods();
        for (Method method : methods) {
            System.out.println(method.getName());
        }
        System.out.println("4========================4");

        //获取当前类中所有的方法,无论什么访问修饰符
        Method[] declaredMethods = clazz.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod.getName());
        }
        System.out.println("5========================5");

        Method add = clazz.getDeclaredMethod("add", int.class, int.class);
        add.setAccessible(true);
        Object o1 = clazz.newInstance();
        add.invoke(o1,123,123);

        System.out.println("6========================6");

        //获取对象的所有构造方法,只能获取公有的改造方法
        Constructor<?>[] constructors = clazz.getConstructors();
        for (Constructor<?> constructor : constructors) {
            System.out.println(constructor.getName());
        }
        System.out.println("7========================7");

        //获取所有的构造方法,无论是私有还是公有
        Constructor<?>[] declaredConstructors = clazz.getDeclaredConstructors();
        for (Constructor<?> declaredConstructor : declaredConstructors) {
            System.out.println(declaredConstructor.getName());
        }
        //如何调用私有的构造方法呢?
        Constructor<?> declaredConstructor = clazz.getDeclaredConstructor(String.class, int.class, String.class);
        declaredConstructor.setAccessible(true);
        Student o2 = (Student)declaredConstructor.newInstance("msb", 23, "java");
        System.out.println(o2);
    }
}



输出:
public java.lang.String com.ycd.reflect.Student.className
className
class java.lang.String
1
-----
public java.lang.String com.ycd.reflect.Person.name
name
class java.lang.String
1
-----
public int com.ycd.reflect.Person.age
age
int
1
-----
1=======================1
className
address
2========================2
address
北京市
3========================3
toString
getAddress
getClassName
setClassName
setAddress
show
wait
wait
wait
equals
hashCode
getClass
notify
notifyAll
4========================4
add
toString
getAddress
getClassName
setClassName
setAddress
5========================5
246
6========================6
com.ycd.reflect.Student
com.ycd.reflect.Student
7========================7
com.ycd.reflect.Student
com.ycd.reflect.Student
com.ycd.reflect.Student
Student{className='java', address='null', name='msb', age=23}

下面利用反射,实现了查询sql操作的应用。

/*
* 要查询N张表的数据,但是不想写N多的方法,能否写一个方法完成所有表的查询工作
*
* */
public class BaseDaoImpl {
    /**
     * 统一的查询表的方法
     * @param sql       不同的sql语句
     * @param params    sql语句的参数
     * @param clazz        sql语句查询返回的对象
     * @return
     */
    public List getRows(String sql,Object[] params,Class clazz){
        List list = new ArrayList();
        Connection connection = null;
        PreparedStatement pstmt = null;
        ResultSet resultSet = null;

        try {
            //建立连接
            connection = DBUtil.getConnection();
            //创建pstmt对象
            pstmt = connection.prepareStatement(sql);
            //给sql语句填充参数
            if(params!=null){
                for(int i = 0;i<params.length;i++){
                    pstmt.setObject(i+1,params[i]);
                }
            }
            //开始执行查询操作,resultset中有返回的结果,需要讲返回的结果放置到不同的对象中
            resultSet = pstmt.executeQuery();
            //获取结果集合的元数据对象
            ResultSetMetaData metaData = resultSet.getMetaData();
            //判断查询到的每一行记录中包含多少个列
            int columnCount = metaData.getColumnCount();
            //循环遍历resultset
            while(resultSet.next()){
                //创建放置具体结果属性的对象
                Object obj = clazz.newInstance();
                for(int i= 0;i<columnCount;i++){
                    //从结果集合中获取单一列的值
                    Object objValue = resultSet.getObject(i+1);
                    //获取列的名称
                    String columnName = metaData.getColumnName(i+1).toLowerCase();
                    //获取类中的属性
                    Field declaredField = clazz.getDeclaredField(columnName);
                    //获取类中属性对应的set方法
                    Method method = clazz.getMethod(getSetName(columnName),declaredField.getType());
                    if(objValue instanceof Number){
                        Number number = (Number) objValue;
                        String fname = declaredField.getType().getName();
                        if("int".equals(fname)||"java.lang.Integer".equals(fname)){
                            method.invoke(obj,number.intValue());
                        }else if("byte".equals(fname)||"java.lang.Byte".equals(fname)){
                            method.invoke(obj,number.byteValue());
                        }else if("short".equals(fname)||"java.lang.Short".equals(fname)){
                            method.invoke(obj,number.shortValue());
                        }else if("long".equals(fname)||"java.lang.Long".equals(fname)){
                            method.invoke(obj,number.longValue());
                        }else if("float".equals(fname)||"java.lang.Float".equals(fname)){
                            method.invoke(obj,number.floatValue());
                        }else if("double".equals(fname)||"java.lang.Double".equals(fname)){
                            method.invoke(obj,number.doubleValue());
                        }
                    }else{
                        method.invoke(obj,objValue);
                    }
                }
                list.add(obj);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            DBUtil.closeConnection(connection,pstmt,resultSet);
        }

        return list;
    }


    public String getSetName(String name){
        return "set"+name.substring(0,1).toUpperCase()+name.substring(1);
    }

    public static void main(String[] args) {
        BaseDaoImpl baseDao = new BaseDaoImpl();
//        List rows = baseDao.getRows("select empno,ename,sal,deptno from emp where deptno =?", new Object[]{10}, Emp.class);
//        for(Iterator it = rows.iterator();it.hasNext();){
//            Emp emp = (Emp) it.next();
//            System.out.println(emp);
//        }
        List rows = baseDao.getRows("select deptno,dname,loc from dept", new Object[]{}, Dept.class);
        for(Iterator it = rows.iterator();it.hasNext();){
            Dept dept = (Dept) it.next();
            System.out.println(dept);
        }
    }
}

相关文章

  • Java基础之反射

    Java基础之反射 反射基本介绍 反射的使用通过反射调用属性和方法通过反射获取配置文件 反射基本介绍 Java反射...

  • 镜面反射矩阵的推导

    镜面反射是以镜面作为反射平面,实物与反射物到反射平面的距离相等,实物与反射物方向相反,所以,反射矩阵由反射平面确定...

  • reflect.go包学习_之二 指针操作提高反射性能 反射应用

    reflect.go包学习_之二 指针操作提高反射性能 反射应用 反射创建实例 反射信息、反射调用方法、反射修改值...

  • Java互联网公司-经典面试题附答案

    基础:Java 反射?反射有什么缺点?你是怎么理解反射的(为什么框架需要反射)?优点:反射具有解耦性,缺点:反射属...

  • Java反射与joor反射库的使用

    java原生反射的使用 反射构造对象 反射方法 反射字段 joor反射库的使用 github:https://gi...

  • Java反射

    什么是反射? 反射的作用? 反射性能优化?

  • 反射三定律

    反射第一定律:反射可以将interface类型变量转换成反射对象 反射第二定律:反射可以将反射对象还原成inter...

  • 反射

    1.反射是什么?反射的定义,概念 2.为什么要学反射? 3.怎么使用反射?反射的使用

  • 一周岁前做好两件事,孩子就不会语言迟缓,保证口齿伶俐

    与语言发展相关的原始反射有四个:张口反射、足跖反射、抓握反射和手拉反射,每个反射的发生、发展和整合都是次第进行的,...

  • 面试官问go反射第一弹

    目录 反射概念 reflect包 反射类型(Type)和种类(Kind) 反射类型(Type)使用 反射类型对象(...

网友评论

    本文标题:反射

    本文链接:https://www.haomeiwen.com/subject/xhpgfktx.html