Day13-reflect反射
来源:互联网 发布:商之翼yii2源码 编辑:程序博客网 时间:2024/06/14 18:40
反射的概念
反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力。(对于Java程序来说,状态和行为就是类的变量和方法)
反射是框架的灵魂!
反射的作用
* - 在运行时判断任意一个对象所属的类(对象.getClass().getName())
* - 在运行时构造任意一个类的对象(不用new,直接使用字节码文件对象就能给你创建对象)
User user1 =(User) class1.newInstance(); user1.say();
* - 在运行时判断任意一个类所具有的成员变量和方法* - 在运行时调用任意一个对象的方法。通过反射甚至可以调用到private方法。* - 生成动态代理(代理模式中的一种)
获得字节码文件的三种方式(没有字节码文件,反射就是空谈)
* - 对象.getClass() connection.getClass()* - 使用Class类的forName()静态方法,全路径类名,该方法最常使用 Class.forName("com.mysql.jdbc.Driver");* - 使用“类型名.class” 类似于User.class * 这个方法其实不能单独使用,后面要加上函数,比如User.class.getName();
获取一个类的全路径名字的小技巧:
选中要获取的类,然后右键点击,选中:Copy Qualified Name
利用字节码生成对象
- 使用无参构造方法,只需调用这个类对应的Class对象的newInstance()方法
User user1 =(User) class1.newInstance();
使用带参数的构造函数生成对象
- Class对象调用getConstructor(参数类型的Class对象),获取带参数的构造函数;
- 构造函数调用newInstance(参数)生成对象
Class<?> forName = Class.forName("com.User");Constructor<?> constructor = forName.getConstructor(int.class,String.class,String.class,String.class); //获取到该类的有参数的构造函数 User user2 =(User) constructor.newInstance(2,"otra","123","rows");//通过有参数的构造函数调用newInstance(参数)方法 user2.say();
Class对象的方法一览
- public String getName()
- 返回此 Class 对象所表示的实体的全限定名称。
-field.get(object)
可以获取指定对象object的某个变量的值。
如果要获取私有变量的值的话,要先把私有变量的权限设置了。
setAccessable(true); - public String getSimpleName()
- 返回此 Class 对象所表示的实体的全限定名称。 - public Field[] getFields()
- 返回此 Class 对象所表示的实体的所有公共属性。 - public Field[] getField(String name)
- 返回此 Class 对象所表示的实体的指定属性名称的公共属性。 - public Field[] getDeclaredFields()
- 返回此 Class 对象所表示的实体的所有属性,包括私有属性,但不包括继承父类的属性。 - public Method[] getMethods()
- 返回此 Class 对象所表示的实体的所有公共属性。(包括父类中的方法) - public Method[] getDeclaredMethods()
- 返回此 Class 对象表示的实体的所有方法,包括私有方法,但不包括继承父类的方法。 - public Method getMethod(String name, Class… parameterTypes)
- 返回此 Class 对象所表示的实体的指定公共成员方法,
- name指定方法名称,parameterTypes指定方法参数类型- public Constructor[] getConstructors()
- 返回此 Class 对象所表示的类的所有公共构造方法。
- public Constructor[] getConstructors()
- public Constructor[] getDeclaredConstructors()
- 返回此 Class 对象表示的类声明的所有构造方法,包括私有构造方法。 - public Constructor getDeclaredConstructor(Class… parameterTypes)
- 返回此 Class 对象所表示的类的指定构造方法。 - public Class
- invoke(Object o,Object... args)
- o是调用该方法的对象,args是调用该方法时传入的参数
案例:
用反射自定义DBUtils,复写DBUtils框架的基本功能:
package com.itheima.myDBUtils;import java.lang.reflect.Method;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.ResultSetMetaData;import java.sql.SQLException;import java.util.ArrayList;import java.util.List;import javax.sql.DataSource;public class MyDBUtils{ DataSource ds; public MyDBUtils(DataSource ds){ super(); this.ds = ds; } public <E> List<E> queryBeenList(String sql,Object[] params,Class<E> clazz) throws Exception{ //建立连接 Connection connection = ds.getConnection(); //创建执行sql语句的对象 PreparedStatement prepareStatement = connection.prepareStatement(sql); //将参数导入都sql语句中去 if(params != null){ for(int i=0;i<params.length;i++){ prepareStatement.setObject(i+1, params[i]); } } //执行sql语句 ResultSet resultSet = prepareStatement.executeQuery(); ResultSetMetaData metaData = prepareStatement.getMetaData(); //获得列数 int columnCount = metaData.getColumnCount(); Method[] methods = clazz.getMethods(); List<E> list = new ArrayList<>(); //处理结果集 while(resultSet.next()){ E e = clazz.newInstance(); //获取列名 for(int i=0;i<columnCount;i++){ //获取列名 String columnName = metaData.getColumnName(1+i); //获取列的值 Object object = resultSet.getObject(columnName); //设置值 for(int j=0;j<methods.length;j++){ if(methods[j].getName().equalsIgnoreCase("set"+columnName)){ methods[j].invoke(e, object); } } } list.add(e); } return list; }}
调用主函数类:
package com.itheima.myDBUtils;import java.util.List;import javax.sql.DataSource;import com.mchange.v2.c3p0.ComboPooledDataSource;public class MainTest02 { public static void main(String[] args) throws Exception { MyDBUtils myDBUtils = new MyDBUtils(new ComboPooledDataSource()); String sql = "select * from userinfo"; List<User> user = myDBUtils.queryBeenList(sql, null, User.class); System.out.println(user); }}
阅读全文
0 0
- Day13-reflect反射
- 反射reflect
- 反射reflect
- 反射Reflect
- 反射Reflect
- Reflect反射
- reflect(反射)
- 反射Reflect
- 反射 Reflect
- reflect(反射)
- reflect--反射
- reflect(反射)
- 反射reflect
- 反射reflect
- day13-事务&mvc&反射补充
- 0610-----反射reflect
- java 反射机制 reflect
- java反射机制reflect
- Spring(五)使用Spring集成MyBatis
- VS2015 安装web essentials导致无法打开MVC视图文件(chtml)
- 图像旋转-不同插值法比较——MATLAB
- Windows环境下的PHP环境的安装及配置—-WAMP
- 依赖ConstraintLayout报错:Could not find com.android.support.constraint:constraint-layout:1.0.0-beta5
- Day13-reflect反射
- 黑化的牛牛
- Tomcat配置连接池【JNDI资源】
- Effective Modern C++: Item 5 -> 优先选择auto而不是显式类型声明
- Mysql之多表设计之外键约束
- java中POJO类为什么要实现序列化
- linux下memcached的安装、php-memcached拓展安装
- 修改mac环境变量
- SparkSQL相关语句总结