文档章节

对java反射的理解,以及应用(实现简易ORM)。

奔跑的码农
 奔跑的码农
发布于 2017/02/14 16:08
字数 926
阅读 148
收藏 0

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>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)的实现原理吧。

© 著作权归作者所有

奔跑的码农

奔跑的码农

粉丝 15
博文 34
码字总数 41797
作品 0
海淀
程序员
私信 提问
MyBatis源码窥探:MyBatis整体架构解析

Mybatis的使用这里就不介绍了,不知道怎么使用的朋友可以点击 http://www.mybatis.org/mybatis-3/zh/index.html 这里面的教程很详细,包括xml的配置、映射、动态sql都有介绍,可以学习和使用...

java邵先生
01/15
0
0
学Android开发,入门语言java知识点

Android是一种以Linux为基础的开源码操作系统,主要使用于便携设备,而linux是用c语言和少量汇编语言写成的,如果你想研究Android,就去学java语言吧。 Android开发入门教程 -Java语言,最差...

抉择很难
2015/12/11
221
0
ORM轻量级框架---ActiveAndroid

ORM即Object-Relational Mapping,对象关系映射。简单理解就是把我们Java的对象与数据库里面的记录进行映射,可以把实体对象持久化到数据库中,也能把查询到的记录映射成Java对象。ORM让我们...

Jack_1900
2014/07/29
2.2K
0
注解(Annotation)--注解处理器

如果没有用来读取注解的方法和工作,那么注解也就不会比注释更有用处了。使用注解的过程中,很重要的一部分就是创建于使用注解处理器。Java SE5扩展了反射机制的API,以帮助程序员快速的构造...

boonya
2015/04/17
136
0
图形化Hibernate框架理解

基于Hibernate框架原理的图形化理解示意图: 图解Hibernate说明: 在Hibernate工作的原理中,它是通过利用数据库以其他的配置如Hibernate.propertie、XML.mapping等来为应用程序(Applicati...

鲁雯雪
2013/12/27
1K
0

没有更多内容

加载失败,请刷新页面

加载更多

Mybatis Plus性能分析

一、配置 /** * 性能分析 * @return */@Bean@Profile({"dev","test"})public PerformanceInterceptor performanceInterceptor (){ PerformanceInterceptor performanceInterceptor......

一个yuanbeth
23分钟前
4
0
一次写shell脚本的经历记录——特殊字符惹的祸

本文首发于微信公众号“我的小碗汤”,扫码文末二维码即可关注,欢迎一起交流! redis在容器化的过程中,涉及到纵向扩pod实例cpu、内存以及redis实例的maxmemory值,statefulset管理的pod需要...

码农实战
26分钟前
4
0
为什么阿里巴巴Java开发手册中不建议在循环体中使用+进行字符串拼接?

之前在阅读《阿里巴巴Java开发手册》时,发现有一条是关于循环体中字符串拼接的建议,具体内容如下: 那么我们首先来用例子来看看在循环体中用 + 或者用 StringBuilder 进行字符串拼接的效率...

武培轩
38分钟前
6
0
队列-链式(c/c++实现)

队列是在线性表功能稍作修改形成的,在生活中排队是不能插队的吧,先排队先得到对待,慢来得排在最后面,这样来就形成了”先进先出“的队列。作用就是通过伟大的程序员来实现算法解决现实生活...

白客C
47分钟前
65
0
聊聊nacos的notifyConfigInfo

序 本文主要研究一下nacos的notifyConfigInfo CommunicationController nacos-1.1.3/config/src/main/java/com/alibaba/nacos/config/server/controller/CommunicationController.java @Cont......

go4it
昨天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部