java 注解与反射
来源:互联网 发布:2016中国人工智能大会 编辑:程序博客网 时间:2024/04/30 22:30
什么是注解(Annotation)
- 不是程序本身,可以对程序作出解释
- 可以被其他程序(比如:编译器等)读取
- 可以附加在package,class,method和field等上面,相当于给他们添加了额外的辅助信息
- 使用@interface自定义注解时,自动继承了java.lang.annotation.Annotation接口
- 如果注解中只有一个参数,通常参数名取为value;在使用注解传参的时候可以省略”value=”
元注解
- @Target(用于描述注解使用的范围)
- @Retention(表示需要在什么级别保存该注释信息,用于描述注解的生命周期)
- @Documented
- @Inherited
/** * 自定义注解 * @author L J *///表示该注解可以用在方法上面,还可以用在类上面@Target(value={ElementType.METHOD, ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)public @interface LjAnnotation { //注解的参数 String studentName() default ""; int age() default 0; int id() default -1; //如果没有传参数,表示不存在}
//测试自定义注解@LjAnnotation(id=1, age=12, studentName="小明")public class LjAnnotationTest { @LjAnnotation public void test() { }}
反射读取注解信息
/** * 用于对象关系映射 * 表示类和表结构对应 * @author L J */@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)public @interface Table { //表名 String value();}
/** * 用于对象关系映射 * 表示属性和字段对应 * @author L J */@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)public @interface LField { //字段名 String columnName(); //字段类型 String type(); //字段长度 int length();}
//学生类@Table("tb_student")public class Student { @LField(columnName="id", type="int", length=10) private int id; @LField(columnName="sname", type="varchar", length=10) private String studentName; @LField(columnName="age", type="int", length=3) private int age; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getStudentName() { return studentName; } public void setStudentName(String studentName) { this.studentName = studentName; } public int getAge() { return age; } public void setAge(int age) { this.age = age; }}
/** * 使用反射读取注解的信息 * 模拟处理注解信息的流程 * @author L J */public class AnnotationDemo { public static void main(String[] args) { try { Class clazz = Class.forName("com.belief.annotation.Student"); //获得所有修饰类的有效注解 Annotation[] annotation = clazz.getAnnotations(); for (Annotation a : annotation) { System.out.println(a); } //获得修饰类的指定的注解 Table t = (Table) clazz.getAnnotation(Table.class); System.out.println(t.value()); //tb_student //获得类的属性的注解 Field f = clazz.getDeclaredField("studentName"); LField field = f.getAnnotation(LField.class); //sname-->varchar-->10 System.out.println(field.columnName() + "-->" + field.type() + "-->" + field.length()); } catch (Exception e) { e.printStackTrace(); } }}
反射
//用户类public class User { private Integer id; private Integer age; private String uname; public User() { } public User(Integer id, Integer age, String uname) { this.id = id; this.age = age; this.uname = uname; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getUname() { return uname; } public void setUname(String uname) { this.uname = uname; }}
Class对象的获取方式:
/** * 测试java.lang.Class对象的获取方式 * @author L J */@SuppressWarnings("all")public class ClassGetTest { public static void main(String[] args) { String path = "com.belief.reflection.User"; try { //一个类被加载后,JVM会创建一个对应该类的Class对象 //类的整个结构信息会放到对应的Class对象中 Class clazz = Class.forName(path); System.out.println(clazz); //class com.belief.reflection.User Class strClazz = String.class; //对象.getClass()方法也可以获得对应类的Class对象 Class strClazz2 = path.getClass(); System.out.println(strClazz == strClazz2); //true //基本数据类型获取Class对象的方式 Class intClazz = int.class; System.out.println(intClazz); //数组的Class对象和维数有关 int[] arr1 = new int[1]; int[] arr2 = new int[2]; int[][] arr3 = new int[1][2]; System.out.println(arr1.getClass() == arr2.getClass()); //true System.out.println(arr1.getClass().hashCode()); //1383884648 System.out.println(arr2.getClass().hashCode()); //1383884648 System.out.println(arr3.getClass().hashCode()); //1701381926 } catch (ClassNotFoundException e) { e.printStackTrace(); } }}
获取类的信息:
/** * 获取类的信息(类的名字、属性、方法、构造器等) * @author L J */@SuppressWarnings("all")public class ReflectionDemo { public static void main(String[] args) { String path = "com.belief.reflection.User"; try { Class clazz = Class.forName(path); //获取类的名字 System.out.println(clazz.getName()); //获取包名+类名 com.belief.reflection.User System.out.println(clazz.getSimpleName()); //获取类名 User //获取属性信息 //Field[] fields = clazz.getFields(); //只能获得public的属性 Field[] fields = clazz.getDeclaredFields(); //获得所有的属性 Field f = clazz.getDeclaredField("uname"); //获得单个属性 for(Field temp : fields) { System.out.println("属性:" + temp); } //获得方法信息 Method[] methods = clazz.getDeclaredMethods(); Method m1 = clazz.getDeclaredMethod("getUname", null); //如果方法有参数,则必须传递参数类型对应的Class对象 Method m2 = clazz.getDeclaredMethod("setUname", String.class); for (Method method : methods) { System.out.println("方法:" + method); } //获得构造器信息 Constructor[] constructors = clazz.getDeclaredConstructors(); for(Constructor temp : constructors) { System.out.println("构造器:" + temp); } Constructor c = clazz.getDeclaredConstructor(Integer.class, Integer.class, String.class); System.out.println("获得构造器:" + c); } catch (Exception e) { e.printStackTrace(); } }}
通过反射API动态的操作:构造器、方法、属性
/** * 通过反射API动态的操作:构造器、方法、属性 * @author L J */@SuppressWarnings("all")public class reflectionDemo2 { public static void main(String[] args) { String path = "com.belief.reflection.User"; try { Class<User> clazz = (Class<User>) Class.forName(path); //通过反射API调用构造方法,构造对象 //其实是调用了User的无参构造方法 User user = clazz.newInstance(); System.out.println(user); //调用有参构造器 Constructor<User> c = clazz.getDeclaredConstructor(Integer.class, Integer.class, String.class); User user2 = c.newInstance(1001, 18, "小明"); System.out.println(user2.getUname()); //小明 //通过反射调用普通方法 User user3 = clazz.newInstance(); Method method = clazz.getDeclaredMethod("setUname", String.class); method.invoke(user3, "隔壁老王"); System.out.println(user3.getUname()); //隔壁老王 //通过反射操作属性 User user4 = clazz.newInstance(); Field f = clazz.getDeclaredField("uname"); f.setAccessible(true); f.set(user4, "哈哈"); System.out.println(f.get(user4)); //哈哈 } catch (Exception e) { e.printStackTrace(); } } }
使用反射操作泛型:
/** * 使用反射操作泛型 * @author L J */@SuppressWarnings("all")public class ReflectionDemo3 { public static void main(String[] args) { try { // 获得指定方法的参数泛型信息 Method m = ReflectionDemo3.class.getMethod("test01", Map.class, List.class); Type[] t = m.getGenericParameterTypes(); for (Type paramType : t) { System.out.println(paramType); if (paramType instanceof ParameterizedType) { Type[] genericTypes = ((ParameterizedType) paramType) .getActualTypeArguments(); for (Type genericType : genericTypes) { System.out.println("泛型类型:" + genericType); } } } // 获得指定方法返回值泛型类型 Method m2 = ReflectionDemo3.class.getMethod("test02", null); Type returnType = m2.getGenericReturnType(); System.out.println(returnType); if (returnType instanceof ParameterizedType) { Type[] genericTypes = ((ParameterizedType) returnType) .getActualTypeArguments(); for (Type genericType : genericTypes) { System.out.println("泛型类型:" + genericType); } } } catch (Exception e) { e.printStackTrace(); } } public void test01(Map<String, User> map, List<User> list) { System.out.println("ReflectionDemo3.test01()"); } public Map<Integer, User> test02() { System.out.println("ReflectionDemo3.test02()"); return null; }}
0 0
- java 注解与反射
- java反射与注解
- Java反射与注解
- JAVA反射与注解
- JAVA反射与注解
- JAVA反射与注解实例
- JAVA反射与注解实例
- Java 基础-反射与注解
- 黑马程序员----JAVA基础反射与注解
- java基础与基础加强反射/注解
- java注解与反射的应用
- 08java基础 之反射与注解
- java注解学习2,注解的定义与反射调用
- 注解与反射
- 反射与注解
- 反射与注解
- 反射与注解
- 注解与反射
- include和merge 布局使减少布局重用
- 程序设计实验Ⅰ期末模拟 解题报告
- 读取网络流获取文件大小
- 【数据库】数据库并发操作(二)数据库并发控制机制
- PHP---XML--simpleXML
- java 注解与反射
- Ubuntu64位编译32位程序
- Linux操作系统支持常用的文件系统有哪些?
- 【数据库】数据库并发操作(一)数据库并发操作带来的问题
- AndroidStudio2.2+环境下的JNI环境搭建
- Eclipse 中 XML 警告 No grammar constraints (DTD or XML Schema) 解决方法
- wmic使用
- Java_java中JFileChooser类(java_swing提供的文件选择对话框)
- 张正友相机标定 Opencv实现