博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
对java反射的理解,以及应用(实现简易ORM)。
阅读量:5823 次
发布时间:2019-06-18

本文共 2615 字,大约阅读时间需要 8 分钟。

hot3.png

1.了解什么是Class类

Class类:当我们定义一个Dog类 class Dog{} 那么这个类在加载时会产生一个对象,是java.lang.Class的实例对象。比如:

class Dog{		private int id;		private String name;		private void say(){		System.out.println("汪汪汪...");	}}Dog dog=new Dog();

我们很清楚的知道dog是Dog类的实例对象,其实Dog这个类在jvm看来本身也是一个对象,他是java.lang.Class类的实例对象。

因为"Class"这个类的构造方法是私有的,我们没有办法通过new这个关键字来构造这个类的对象(dog),但是可以通过以下几个方法来构造这个类:

Class c=Dog.class;//通过类名获得Class类的对象(任何一个类都有隐含的成员变量Class)	Class c=dog.getClass();	Class c=Class.forName("com.Dog");//这里写完整的类路径

通过以上方式我们获得了Class类的对象 c 它称为类的类型(class type)。

那么我们想要通过Dog类的对象dog除了Dog dog=new Dog()我们还可以通过获得的c来创建Dog类的实例:

Dog dog=(Dog)c.newInstance();//注意强制类型转换

其中Class.forName("类的全路径"),这是动态加载类,我们学习mysql时通过Class.forName("com.myql.jdbc.Driver"); 此时即使我们没有导入驱动的包它也不会报错,当我们真正运行时才会抛出找不到驱动类的异常。由此可以看出他是在运行时动态加载的。

我们常用的变量也会有Class的类类型(class type),比如:

Class c1=int.class;	Class c2=String.class;	Class c3=void.class;

当我们要获得类的名称时可以通过 c1.getName();此时返回 int, c2.getName()此时返回java.lang.String.

我们可以通过Class的函数获得各种信息,比如下面几个方法;

String className=c.getName();//获得了类的名称	Method[] ms=c.getMethods();//获得了Dog类以及从父类继承的所有public方法	Method[] ms=c.getDeclaredMethods();//获得类Dog类定义的所有方法	/*	 * 此时我们可以对获得的方法数组进行遍历	 */	for(Method method:ms){		Class returnType=method.getReturnType();//得到了返回值的类型		String methodName=method.getName();//得到了返回值的名字	}

也可以得到成员变量的信息:(具体的自己参考帮助文档)

Field[] fs=c.getFields();//获得public类型的所有成员变量信息	Field[] fs=c.getDeclaredFields();//获得Dog类的所有成员变量

我们可以通过反射来调用私有的方法:

/**	 * c.getMethod(name, parameterTypes)获取的是public的方法	 * c.getDeclaredMethod(name, parameterTypes)自己声明的方法	 */	Method m=c.getDeclaredMethod("say", new Class[]{});	m.invoke(dog, new Object[]{});

以上我们调用了Dog的say方法。其中new Class[]{}为方法需要的参数,因为say方法不需要参数所以是空数组。

因此我们可以利用上述知识来完成一个自己的orm框架,传入任何一个对象将其存到数据库中。

public static 
T save(T entity){ String tableName=entity.getClass().getAnnotation(Table.class).name(); String sql="insert into "+tableName+"("; String cols=""; String values=""; for(Field field:entity.getClass().getDeclaredFields()){//注意getFields()只能获得public访问权限的值,getDeclaredFields()可以获得所有的 String colName=field.getAnnotation(Column.class).name(); cols+=colName+","; try{ field.setAccessible(true);//通过反射访问该field时不受权限控制 if(field.getType().equals(String.class)) values+="'"+field.get(entity)+"',"; else values+=field.get(entity)+","; }catch(Exception e){ } } cols=cols.substring(0, cols.length()-1); values=values.substring(0, values.length()-1); sql+=cols+")values("+values+")"; System.out.println("SQL语句为:"+sql); //此时已经完整的拿到了sql语句,接下来执行改语句即可。 return null; }

我想这就是数据持久化框架(如Hibernate)的实现原理吧。

转载于:https://my.oschina.net/wang520/blog/838520

你可能感兴趣的文章
线性表4 - 数据结构和算法09
查看>>
C语言数据类型char
查看>>
Online Patching--EBS R12.2最大的改进
查看>>
Binary Search Tree Iterator leetcode
查看>>
uva-317-找规律
查看>>
Event事件的兼容性(转)
查看>>
我的2014-相对奢侈的生活
查看>>
zoj 2412 dfs 求连通分量的个数
查看>>
Java设计模式
查看>>
一文读懂 AOP | 你想要的最全面 AOP 方法探讨
查看>>
Spring Cloud 微服务分布式链路跟踪 Sleuth 与 Zipkin
查看>>
ORM数据库框架 SQLite 常用数据库框架比较 MD
查看>>
华为OJ 名字美丽度
查看>>
微信公众号与APP微信第三方登录账号打通
查看>>
onchange()事件的应用
查看>>
Windows 下最佳的 C++ 开发的 IDE 是什么?
查看>>
软件工程师成长为架构师必备的十项技能
查看>>
python 异常
查看>>
百度账号注销
查看>>
mysql-This version of MySQL doesn’t yet support ‘LIMIT & IN/ALL/ANY/SOME 错误解决
查看>>