java注解与反射
内置注解:
@Override //表示重写超类的方法
@Deprecated //表示不推荐使用或过时,但可以使用
@SuppressWarnings("all") //用来抑制编译时的所有警告
@SuppressWarnings("unchecked") //未检查的警告
@SuppressWarnings(value={"unchecked","deprecation"}) //多个警告类型
元注解:
/*下面是定义一个注解的操作*/ @Target(value = {ElementType.METHOD,ElementType.TYPE}) //该注解能在哪些地方使用,可传递多个参数 @Retention(value = RetentionPolicy.RUNTIME) //表示注解生效位置RUNTIME>CLASS>RESOURCES @Documented //表示是否将我们的注解生成在javadoc中 @Inherited //子类可继承父类的注解 @interface MyAnotation{ //自定义的注解 }
自定义注解:
@Target({ElementType.TYPE,ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @interface MyAnotaion{ //注解的参数 :参数类型 + 参数名(); String name() default ""; //值默认为空 int id() default -1; //如果默认为-1代表不存在 String[] schools() default {"南京大学","天津大学"}; } //如果注解内部参数只有一个,那么可以直接参数类型+value() //如:String value(); //使用注解设置值时可以不用键:@MyAnotation("张三")。不然只能这样: //@MyAnotaion(name="张三",age=18)设置值;
反射:
public void test(){ //获取系统类加载器 ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); System.out.println("系统类加载器:" + systemClassLoader); //获取系统类加载器:拓展类加载器: ClassLoader parent = systemClassLoader.getParent(); System.out.println("拓展类加载器:" + parent); //获取拓展类加载器:根加载器 ClassLoader parent1 = parent.getParent(); System.out.println("根加载器" + parent1); //测试当前类是哪个加载器加载的 Class<ClassLoaderDemoTest> classLoaderDemoTestClass = ClassLoaderDemoTest.class; System.out.println("当前类是:"+classLoaderDemoTestClass.getClassLoader()+"加载的"); }
输出:
获取类运行时结构:
public void Test() throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException { Class<?> aClass = Class.forName("pojo.User"); System.out.println(aClass.getName()); //获取包名加类名 System.out.println(aClass.getSimpleName()); //获取类名 Field[] fields = aClass.getFields(); //获取类所有公开属性名 Field[] declaredFields = aClass.getDeclaredFields(); //获取类所有属性 System.out.println(aClass.getDeclaredField("username")); //获取指定属性 Method[] methods = aClass.getMethods(); //获取本类与父类所有公开方法 Method[] declaredMethods = aClass.getDeclaredMethods(); //获取本类所有方法 Method getId = aClass.getDeclaredMethod("setId",int.class); //获取指定方法 Constructor<?>[] constructors = aClass.getConstructors(); //获取所有公共构造器 Constructor<?>[] declaredConstructors = aClass.getDeclaredConstructors(); //获取所有构造器 Constructor<?> declaredConstructor = aClass.getDeclaredConstructor(int.class,String.class,String.class,String.class,String.class); //获取指定构造器 System.out.println(declaredConstructor); }
动态创建对象,执行方法:
public void test1() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException { Class<?> aClass = Class.forName("pojo.Student"); Student student = (Student)aClass.newInstance(); //构造一个对象,本质调用无参构造 Constructor<?> declaredConstructor = aClass.getDeclaredConstructor(String.class, int.class); //获取一个有参构造器 Object wmskywm = declaredConstructor.newInstance("wmskywm", 18);//构造一个对象 Student student1 = (Student) aClass.newInstance(); Method setSname = aClass.getDeclaredMethod("show"); //反射拿到一个类的方法 setSname.invoke(student1,"wangming"); //激活方法设置student1的值 System.out.println(student1); //输出Student(sname=wangming, sage=0) Field sname = aClass.getDeclaredField("sname"); sname.setAccessible(true); //不能直接操作公共方法,需要关闭安全检测 sname.set(student1,"小明"); System.out.println(student1); }
性能对比:
普通调用方法 > 关掉安全检测使用反射 > 使用反射
反射操作泛型例子:
public class TestDemo1 { private Map<String,User> map; public void test01(Map<String, User> userMap, List<User> userList) { System.out.println("test01"); } public Map<String,User> test02(){ System.out.println("test02"); return null; } @Test public void test03() throws NoSuchMethodException, NoSuchFieldException { /*获取方法参数类型的泛型*/ Method test01 = TestDemo1.class.getDeclaredMethod("test01", Map.class, List.class); //获取TestDemo01反射Class中的test01方法 Type[] genericParameterTypes = test01.getGenericParameterTypes(); //获取方法中的参数 for (Type genericParameterType : genericParameterTypes) { //遍历参数 System.out.println("#"+genericParameterType); /*输出 #java.util.Map<java.lang.String, pojo.User> #java.util.List<pojo.User> */ if(genericParameterType instanceof ParameterizedType){ Type[] actualTypeArguments = ((ParameterizedType) genericParameterType).getActualTypeArguments(); //获取参数的泛型 for (Type actualTypeArgument : actualTypeArguments) { //遍历参数中的泛型 System.out.println("#"+actualTypeArgument); /*输出: #java.util.Map<java.lang.String, pojo.User> #class java.lang.String#class pojo.User #java.util.List<pojo.User> #class pojo.User */ } } } /*获取方法返回类型的泛型*/ Method test02 = TestDemo1.class.getDeclaredMethod("test02", null); //获取TestDemo01反射Class中的test02方法 Type genericReturnType = test02.getGenericReturnType(); //获取返回test02方法的参数类型 if(genericReturnType instanceof ParameterizedType){ Type[] actualTypeArguments = ((ParameterizedType) genericReturnType).getActualTypeArguments(); //获取参数的泛型 for (Type actualTypeArgument : actualTypeArguments) { //遍历参数中的泛型 System.out.println("#"+actualTypeArgument); /*输出: #class java.lang.String #class pojo.User */ } } /*获取类属性泛型*/ Field map = TestDemo1.class.getDeclaredField("map"); Type genericType = map.getGenericType(); System.out.println(genericType); if(genericType instanceof ParameterizedType){ Type[] actualTypeArguments = ((ParameterizedType) genericType).getActualTypeArguments(); //获取参数的泛型 for (Type actualTypeArgument : actualTypeArguments) { //遍历参数中的泛型 System.out.println("#"+actualTypeArgument); /*输出: #class java.lang.String #class pojo.User */ } } } }
反射操作注解:
表user1
create table user1( uid int(10), uname varchar(10), upwd varchar(10) );
对应表user1的实体类:
@Data @NoArgsConstructor @AllArgsConstructor @ToString @Table_User1("Table_User1") public //类上注解为User1表 class User1 { @Field_User1(columnName = "user1_uid",type = "int",length = 10) private int uid; @Field_User1(columnName = "user1_uname",type = "varchar",length = 10) private String uname; @Field_User1(columnName = "user1_upwd",type = "varchar",length = 10) private String upwd; }
注解:Table_User1:
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface Table_User1{ String value(); }
注解:Field_User1:
@Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface Field_User1{ String columnName(); String type(); int length(); }
反射获取注解的代码:
@Test public void test() throws NoSuchFieldException { Class user1Class = User1.class; /*通过反射获取注解*/ Annotation[] annotations = user1Class.getAnnotations(); for (Annotation annotation : annotations) { System.out.println(annotation); /*输出:@pojo.Table_User1(value="Table_User1")*/ } /*获取注解内容*/ Table_User1 annotations2 = (Table_User1) user1Class.getAnnotation(Table_User1.class); String val = annotations2.value(); System.out.println(val); /*获取类制定注解*/ Field uid = user1Class.getDeclaredField("uid"); Field_User1 annotation = uid.getAnnotation(Field_User1.class); System.out.println(annotation.columnName()); System.out.println(annotation.type()); System.out.println(annotation.length()); }