阿哲学了就来聊——Java反射

在这里插入图片描述

概念

reflect 反射 ,反转 权力的转让
类中有很多的方法和属性,方法的调用权限,属性的赋值权限,属于对象的。
让对象把这些权力交出来,交给Class和其它反射类(Field,Method,Contructor)管理。

Class类 的范围就是天下所有的字节码文件,每一个类被编译成字节码文件后,都可以看成是Class类的对象

反射

  • 与Java反射相关的类如下:
类名用途
Class类代表类的实体,在运行的Java程序中表示类和接口
Field类代表成员变量(成员变量也成为属性)
Mehod代表类的方法
Construtor类代表类的构造方法

Class类

Class类代表实体,在运行Java应用程序中表示类和接口。这个类中提供了很多有用的方法,这里对他们的分类进行简单介绍。

获得类的相关方法

方法用途
asSubclass(Class class)把传递的类和对象转换成代表其子类的对象
Cast把对象转换成代表类或是接口对象
getClassLoader()获得类的加载器
getClasses()返回一个数组,该数组中含该类中有所有的公共类和接口类的对象
getDeclaredClasses返回一个数组,该数组中包含该类所有的类和接口对象
forName(String className)根据类返回类的对象
getName()获得类的完整路径名字
newInstance()创建类的实例
getPackage()获得类的包
getSimpleName()获得类的名字
getSuperclass()获得当前类继承的父类的名字
getInterfaces()获得当前实现的类或者是接口

获得类中属性相关的方法

方法用途
getFiled(String name)获得某个共有的属性对象
getDFileds()获得所有的共有属性对象
getDeclaredFiled ( String name )获得某个属性对象
getDeclaredFileds ( String name )获得所有属性对象

获得类中构造器的相关方法

方法用途
getMethod(String name, Class…<?> parameterTypes)获得该类某个公有的方法
getMethods()获得该类所有公有的方法
getDeclaredMethod(String name, Class…<?> parameterTypes)获得该类某个方法
getDeclaredMethods()获得该类所有方法

Field

Field代表类的成员变量(成员变量也称为类的属性)。

方法用途
equals(Object obj)属性与obj相等则返回true
get(Object obj)获得obj中对应的属性值
set(Object obj, Object value)设置obj中对应属性值

Method类

Method代表类的方法。

方法用途
invoke(Object obj, Object… args)传递object对象及参数调用该对象对应的方法

Constructor类

Constructor代表类的构造方法。

方法用途
newInstance(Object… initargs)根据传递的参数创建类的对象

作用

  • 获取Class对象
@Test
public void test1(){
    // 1.获取某个类的实体类对象:三种方式
    Class<Emps> c1 = Emps.class;
    Class<?extends Emps> c2 = new Emps().getClass();
    try {
        Class<?> c3 = Class.forName("com.web.pojo.Emps");
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
    //2.分别对实体类的成员(属性,方法,构造方法)进行托管
}

构造方法

@Test//使用构造器管理实体类中的构造方法
    public void test2() throws Exception {
        // 1.获取class对象对象:三种方式
        Class<Emps> c1 = Emps.class;

        //2.获取构造方法的管理类
            //2.1托管无参构造
            Emps emps =  c1.newInstance();

            //2.2托管有参构造
        Constructor<Emps> Constructor = c1.getDeclaredConstructor(Integer.class, String.class);
        Emps emps1 = Constructor.newInstance(1, "元歌");
        System.out.println(emps);
        System.out.println(emps1);
    }

普通方法

@Test//使用Method类,来管理实体类中的某个方法
public void test4() throws Exception {
    // 1.获取class对象对象
    Class<Emps> c1 = Emps.class;

    //2.获取某个方法的管理类Method
    Method method = c1.getDeclaredMethod("setName", String.class);
    Emps emps = c1.newInstance();
    System.out.println(emps);
    method.invoke(emps,"韩信");
    System.out.println(emps);

    System.out.println("--------调用toString------");
    Method method1 = c1.getDeclaredMethod("toString");
    Object invoke = method1.invoke(emps);
    System.out.println(invoke);

}

属性

@Test//使用field类,来管理实体类中的某个属性
public void test3() throws Exception {
    // 1.获取class对象对象:三种方式
    Class<Emps> c1 = Emps.class;

    //2.获取某个属性的管理类Field
    Field f1 = c1.getDeclaredField("name");
    Field f2 = c1.getDeclaredField("age");
    Emps emps = c1.newInstance();
    //3.开启私有属性的操作权限
    f1.setAccessible(true);
    f2.setAccessible(true);


    System.out.println(emps);
    f1.set(emps,"孙尚香");
    f2.set(emps,18);
    System.out.println(emps);
}

反射案例

实现DBUtils工具类

封装查询结果集的原理
实用多个数据表格的通用查询
package com.web.jdbc;
import java.lang.reflect.Field;
import java.sql.*;
import java.util.*;



public class JdbcUtil {
    //封装结果集的通用方法
    public static <T> List<T> rsToList(String sql,Class<T> c){

        ArrayList<T> list = new ArrayList<>();
        //加载驱动,获取连接对象
        try {
            //加载驱动,获取连接对象
            Class.forName("com.mysql.jdbc.Driver");
            Connection con = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/wuhanhb?useSSL=false", "root", "root");
            //获取执行sql对象,执行sql,返回结果集rs
            PreparedStatement psmt = con.prepareStatement(sql);
            ResultSet rs = psmt.executeQuery(sql);
            //3.遍历rs
               //3.1借助元数据,获取列名和总列数
            ResultSetMetaData md = rs.getMetaData();
            int conut = md.getColumnCount();
            while (rs.next()){
                //循环一次获取一行数据,调用一次Object获取一个单元格的数据
                T t = c.newInstance();
                for (int i=1;i<=conut;i++) {
                    Object value = rs.getObject(i);
                        //每一列的列名充当T中的属性名,获取对应的属性管理对象f
                    Field f = c.getDeclaredField(md.getColumnName(i));
                    f.setAccessible(true);
                    //为私有属性赋值
                    f.set(t,value);
                }
                list.add(t);

            }
            return list;

        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }



    }
}

测试代码

查询emps数据表

  • 这是数据库中的数据
    数据库中的数据
  • 这是测试类代码(Emps实体类不单独贴出)
@Test
public void test5(){
    //测试jdbc工具类
    List<Emps> emps = JdbcUtil.rsToList("select * from emps", Emps.class);
    System.out.println(emps);
}
  • 查询结果
    查询emps表

查询dept数据表

  • 这是数据库中的数据
    dept数据
  • 这是测试类代码(Emps实体类不单独贴出)
@Test
public void test5(){
    //测试jdbc工具类
    List<Dept> dept = JdbcUtil.rsToList("select * from dept", Dept.class);
    System.out.println(dept);
}

D

  • 查询结果
    dept表查询结果

git 源码

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值