一:反射(Reflect)
1.1、概要
概要:动态获取类的信息,以及动态调用对象的方法的功能(运行时获得并使用类的信息的方法叫反射)
1.2、主要功能
主要功能:
-
- 在运行时判断任意一个对象所属的类;
- 在运行时构造任意一个类的对象;
- 在运行时判断任意一个类所具有的成员变量和方法;
- 在运行时调用任意一个对象的方法
1.3、Class
class的解释:
-
- class 定义类的关键字
- class 每个类都具备的class静态属性
- Class类 描述类的类型信息
1.4、反射常用方法
通过对象获得 | 对象.getClass() |
通过字符串获得(包名+类名) | Class.forName(“包名.类名”) |
通过类的静态成员获得Class | 类名.class |
只针对内置的基本数据类型(String为引用数据类型) | 基本数据类型的引用类型.TYPE 如:Integer.Type |
获得自己的所有字段 | Field[] field=class.getDeclaredFields(); |
获得所有public的字段(包括父类的) | Field[] field=class.getFields(); |
获得方法(根据方法名) | class.getMethod("方法名"); |
调用方法 | method.invoke(对象,有参数加参数); |
获得实例对象 | class.newInstance |
设置私有字段可以访问 | class.setAccessible(true); |
二:反射应用场景
三:注解
3.1、注解的定义
Java 注解就像修饰符一样,可以用于从java代码中抽取文档、跟踪代码中的依赖性或者在编译时做检查。注解可以被应用在包、类、方法、成员变量、参数和本地变量的声明中。我们大多数人最先接触的注解就是@Override。
注解的工作原理就是,先使用注解修饰java代码,然后另一块叫做注解处理器的代码会解析这段注解和被修饰的代码并做相应的处理。
3.2、内置注解
1.)Override
java.lang.Override是一个标记类型注解,它被用作标注方法。它说明了被标注的方法重载了父类的方法,起到了断言的作用。如果我们使用了这种注解在一个没有覆盖父类方法的方法时,java编译器将以一个编译错误来警示。
2.)Deprecated
Deprecated也是一种标记类型注解。当一个类型或者类型成员使用@Deprecated修饰的话,编译器将不鼓励使用这个被标注的程序元素。所以使用这种修饰具有一定的“延续性”:如果我们在代码中通过继承或者覆盖的方式使用了这个过时的类型或者成员,虽然继承或者覆盖后的类型或者成员并不是被声明为@Deprecated,但编译器仍然要报警。
3.)SuppressWarnings
SuppressWarning不是一个标记类型注解。它有一个类型为String[]的成员,这个成员的值为被禁止的警告名。对于javac编译器来讲,被-Xlint选项有效的警告名也同样对@SuppressWarings有效,同时编译器忽略掉无法识别的警告名。
@SuppressWarnings("unchecked")
3.3、元注解(注解的注解)
java.lang.annotation提供了四种元注解,专门注解其他的注解(在自定义注解的时候,需要使用到元注解):
@Documented –注解是否将包含在JavaDoc中
@Retention –什么时候使用该注解
@Target –注解用于什么地方
@Inherited – 是否允许子类继承该注解
四:自定义注解
自定义注解类编写的一些规则:
1. Annotation型定义为@interface, 所有的Annotation会自动继承java.lang.Annotation这一接口,并且不能再去继承别的类或是接口。
2. 参数成员只能用public或默认(default)这两个访问权修饰
3. 参数成员只能用基本类型byte,short,char,int,long,float,double,boolean八种基本数据类型和String、Enum、Class、annotations等数据类型,以及这一些类型的数组.
4. 要获取类方法和字段的注解信息,必须通过Java的反射技术来获取 Annotation对象,因为你除此之外没有别的获取注解对象的方法
5. 注解也可以没有定义成员,自定义注解需要使用到元注解
事例:
package Annotation; import java.lang.annotation.*; @Retention(RetentionPolicy.RUNTIME) @Target(value={ElementType.FIELD,ElementType.TYPE}) @Inherited public @interface Ailas { public String value() default ""; public boolean isGenerator() default false; public boolean isNull() default true; public boolean isPrimary() default false; }
五:反射结合注解
生成简单的SQL脚本
package Annotation; import java.lang.reflect.Field; public class CreateSQLScript { public static void main(String[] mag) throws Exception { System.out.println("查询:"+creteSelectScript("Fruits")); System.out.println("修改:"+creteUpdateScript("Fruits")); System.out.println("删除:"+creteDeleteScript("Fruits")); System.out.println("添加:"+creteInsertScript("Fruits")); System.out.println("新建:"+creteTableScript("Fruits")); } public static String creteSelectScript(String clas) throws Exception { String SqlSelect = "select "; Class clazz = Class.forName("reflect." + clas + ""); Field[] fields = clazz.getDeclaredFields(); String temp = ""; for (Field f : fields) { SqlSelect += temp + f.getName(); temp = ","; } SqlSelect += " form"; Ailas classAlias = (Ailas) clazz.getDeclaredAnnotation(Ailas.class); if (classAlias != null) { //获得注解中value的值 SqlSelect += " " + classAlias.value(); } else { SqlSelect += " " + clazz.getSimpleName(); } return SqlSelect; } public static String creteUpdateScript(String clas) throws Exception { Class clazz = Class.forName("reflect." + clas + ""); String sql = "update ";// UPDATE student SET Sname="李军" WHERE Sno="101" Ailas classAlias = (Ailas) clazz.getDeclaredAnnotation(Ailas.class); if (classAlias != null) { //获得注解中value的值 sql += " " + classAlias.value() + " "; } else { sql += " " + clazz.getSimpleName() + " "; } Field[] fields = clazz.getDeclaredFields(); sql += " set "; String temp = ""; String primary=""; for (Field f : fields) { Ailas fieldAlias = f.getDeclaredAnnotation(Ailas.class); if(fieldAlias!=null){ if(fieldAlias.isPrimary()){ primary=f.getName(); continue; } } sql += temp + f.getName() + "=?"; temp = ","; } sql += " where " + primary + "=?"; return sql; } public static String creteDeleteScript(String clas) throws Exception { Class clazz = Class.forName("reflect." + clas + ""); String sql = " DELETE FROM ";// DELETE FROM fruits WHERE name="西瓜" Ailas classAlias = (Ailas) clazz.getDeclaredAnnotation(Ailas.class); if (classAlias != null) { //获得注解中value的值 sql += " " + classAlias.value() + " "; } else { sql += " " + clazz.getSimpleName() + " "; } Field[] fields = clazz.getDeclaredFields(); sql += " form "; sql += " where " + fields[0].getName() + "=?"; return sql; } public static String creteInsertScript(String clas) throws Exception { Class clazz = Class.forName("reflect." + clas + ""); String sql = " insert into";// insert into Student(Sno,Sname,Ssex,Sbirthday,Class) values('108','曾华','男','1977-09-01','95033'); Ailas classAlias = (Ailas) clazz.getDeclaredAnnotation(Ailas.class); if (classAlias != null) { //获得注解中value的值 sql += " " + classAlias.value() + "("; } else { sql += " " + clazz.getSimpleName() + "("; } Field[] fields = clazz.getDeclaredFields(); String temp = ""; for (Field f : fields) { sql += temp + f.getName() + " "; temp = ","; } sql += ")values("; temp = ""; for (Field f : fields) { sql += temp + "?"; temp = ","; } sql += ")"; return sql; } public static String creteTableScript(String clas) throws Exception { Class clazz = Class.forName("reflect." + clas + ""); String sql = " create table "; // /* create table Student /*学生表*/ // ( //// Sno Char(3) not null primary key, /*学号(主码)*/ //// Sname Char (8) not null, /*学生姓名*/ //// Ssex Char(2) not null, /*学生性别*/ //// Sbirthday datetime, /*学生出生年月*/ // class Char (5) /*学生所在班级*/ //)*/ Ailas classAlias = (Ailas) clazz.getDeclaredAnnotation(Ailas.class); if (classAlias != null) { //获得注解中value的值 sql += " " + classAlias.value() + "("; } else { sql += " " + clazz.getSimpleName() + "("; } Field[] fields = clazz.getDeclaredFields(); String temp = ""; for (Field f : fields) { String[] type = f.getType().toString().split("[.]"); sql += temp + f.getName() + " "; if (type[(type.length) - 1].equals("String")) { sql += "varchar"; } else if (type[(type.length) - 1].equals("double")) { sql += "Money"; } else if (type[(type.length) - 1].equals("Date")) { sql += "datetime"; } Ailas fieldAlias = (Ailas) f.getDeclaredAnnotation(Ailas.class); if (fieldAlias != null) { if (!fieldAlias.isNull()) { sql += " not null"; } if (fieldAlias.isPrimary()) { sql += " primary key "; } } temp = ","; } sql += ")"; return sql; } }