目录
1 简介
1.1 注解
注解是java5引入的一种代码辅助工具,它的核心作用是对类、方法、变量、参数和包进行标注,通过反射来访问这些标注信息,以此在运行时改变所注解对象的行为。Java中的注解由内置注解和元注解组成。
注解与注释的区别:普通的注释在编译后的class文件中是不存在的,而注解附加的信息则可以根据需要保存到class文件中,甚至运行期加载的Class对象中。
元注解:
- @Retention 定义列表的生命周期:SOURCE、CLASS、RUNTIME
- @Documented 文档注解,会被Javadoc工具文档化
- @Inherited 是否让子类继承该注解
- @Target 描述了注解的应用范围
1.2 反射
在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能为Java语言的反射。
反射的优缺点:
-
通过反射可以使程序代码访问装载到JVN中的类的内部信息,获取已装载类的属性信、方法和构造方法信息
-
反射提高了Java程序的灵活性和扩展性,降低耦合性,提高自适应能力
-
反射会对性能造成一定的影响,同时让代码的可读性变差
常用API:
2 学习DEMO
目录结构:
2.1 反射常用API练习
实体类:
package com.education.subject.model; import com.education.subject.annotation.UserAnno; /** * @program: interview * @description: 用户 * @author: onion * @create: 2020-06-09 15:48 **/ @UserAnno(mores={"渔翁","渔阳"}) public class User { private String id; @UserAnno(name="hohoho", mores={"渔翁","渔阳"}) private String name; public String getId() { return id; } public void setId(String id) { this.id = id; } @UserAnno(name="hahaha", mores={"渔翁","渔阳"}) public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "User{" + "id='" + id + '\'' + ", name='" + name + '\'' + '}'; } }
自定义注解:
package com.education.subject.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * @program: interview * @description: * @author: onion * @create: 2020-06-09 15:46 **/ @Target({ElementType.TYPE,ElementType.METHOD,ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) public @interface UserAnno { String name() default "渔樵"; String[] mores(); }
反射Demo类:
package com.education.subject.reflection; import com.education.subject.annotation.UserAnno; import com.education.subject.model.User; import java.lang.reflect.Field; import java.lang.reflect.Method; /** * @program: interview * @description: 反射练习 * @author: onion * @create: 2020-06-09 15:49 **/ public class ReflectionDemo { public static void main(String[] args) throws Exception { reflextion(); } /** * 反射 * @throws Exception */ private static void reflextion() throws Exception { // 1:获取类的元信息(方法一) User user = new User(); Class<? extends User> aClass = user.getClass(); System.out.println(aClass); // 获取类的元信息(方法二) // Class<?> aClass1 = Class.forName("com.education.subject.model.User"); // System.out.println(aClass1); // 获取类名、包名 System.out.println(aClass.getName()); System.out.println(aClass.getSimpleName()); // 2:获取当前类中的所有属性 Field[] fields = aClass.getDeclaredFields(); for (Field tmp : fields) { System.out.println(tmp); } // 获取指定的属性 Field field = aClass.getDeclaredField("id"); System.out.println(field); // 获取属性具体的值 user.setId("10001"); user.setName("渔夫"); for (Field tmp : fields) { // 设置当前属性为可见 tmp.setAccessible(true); System.out.println(tmp.get(user)); } // 反射中的实例化 Object obj = aClass.newInstance(); for (Field tmp : fields) { tmp.setAccessible(true); if (tmp.getName().equals("id")) { tmp.set(obj, "10002"); } else { tmp.set(obj, "渔民"); } System.out.println(tmp.get(obj)); } // 3:反射获取当前类的方法 Method[] methods = aClass.getMethods(); for(Method m : methods){ System.out.println(m.getName()); } // 通过反射执行方法 Method m = aClass.getMethod("toString"); Object invoke = m.invoke(user); System.out.println(invoke); // 4:注解 UserAnno userAnno = aClass.getAnnotation(UserAnno.class); System.out.println(userAnno); String name = userAnno.name(); String[] mores = userAnno.mores(); for(String tmp : mores){ System.out.println(tmp); } System.out.println(name); // 从方法上获得注解 for(Method tmp : methods){ UserAnno userAnno2 = tmp.getAnnotation(UserAnno.class); if(userAnno2 == null){ continue; } String name2 = userAnno2.name(); String[] mores2 = userAnno2.mores(); for(String tmp2 : mores2){ System.out.println(tmp2); } System.out.println(name2); } // 从属性上获得注解 for(Field tmp : fields){ UserAnno userAnno3 = tmp.getAnnotation(UserAnno.class); if(userAnno3 == null){ continue; } String name3 = userAnno3.name(); String[] mores3 = userAnno3.mores(); for(String tmp2 : mores3){ System.out.println(tmp2); } System.out.println(name3); } } }
2.2 通过注解实现自动生成sql语句
实体类:
package com.education.subject.model; import com.education.subject.annotation.CuColumn; import com.education.subject.annotation.CuTable; /** * @program: interview * @description: 学生 * @author: onion * @create: 2020-06-09 18:06 **/ @CuTable(name="tb_student") public class Student { @CuColumn() private String id; @CuColumn(name="c_name") private String name; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Student{" + "id='" + id + '\'' + ", name='" + name + '\'' + '}'; } }
自定义注解:
package com.education.subject.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * @program: interview * @description: 列注解 * @author: onion * @create: 2020-06-09 17:25 **/ @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface CuColumn { String name() default ""; }
package com.education.subject.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * @program: interview * @description: 表名注解 * @author: onion * @create: 2020-06-09 17:20 **/ @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface CuTable { String name() default ""; }
工具类:
package com.education.subject.util; import com.education.subject.annotation.CuColumn; import com.education.subject.annotation.CuTable; import java.lang.reflect.Field; /** * @program: interview * @description: 生成sql工具类 * @author: onion * @create: 2020-06-09 17:13 **/ public class GenerateSqlUtil { /** * 查询:select 字段 from 表名 where 条件 * @param obj * @return * @throws Exception */ public String query(Object obj) throws Exception{ StringBuffer sb = new StringBuffer(); StringBuffer sb2 = new StringBuffer(); sb.append("select "); sb2.append(" where 1=1"); // 反射机制 Class<?> aClass = obj.getClass(); // 获取表名 CuTable annotation = aClass.getAnnotation(CuTable.class); if(annotation == null){ throw new RuntimeException(); } String tableName = ""; if("".equals(annotation.name())){ tableName = aClass.getSimpleName(); }else{ tableName = annotation.name(); } // 列名 Field[] fields = aClass.getDeclaredFields(); for(Field tmp : fields) { CuColumn annotation1 = tmp.getAnnotation(CuColumn.class); // 过滤没有注解的属性 if(annotation1 == null){ continue; } tmp.setAccessible(true); String columnName = "";// 列名 String columnValue = "";// 列值 if("".equals(annotation1.name())){ columnName = tmp.getName(); }else{ columnName = annotation1.name(); } sb.append(columnName + ","); if(tmp.get(obj) != null && !"".equals((String)tmp.get(obj))){ sb2.append(" and " + columnName + "=" + (String)tmp.get(obj)); } } sb.substring(0,sb.length() - 2 ); return sb.append(" from " + tableName).append(sb2).toString(); } }
测试类:
package com.education.test; import com.education.subject.model.Student; import com.education.subject.model.User; import com.education.subject.util.GenerateSqlUtil; /** * @program: interview * @description: * @author: onion * @create: 2020-06-09 18:04 **/ public class Test { public static void main(String[] args) throws Exception { GenerateSqlUtil generateSqlUtil = new GenerateSqlUtil(); Student student = new Student(); student.setId("10003"); student.setName("hohoho"); String sqlStr = generateSqlUtil.query(student); System.out.println(sqlStr); } }
3 学习总结
还行吧,哈哈哈