Java SE(注解与反射)
程序员文章站
2022-06-09 20:44:11
...
注解与反射
注解
-
内置注解
package com.java.annotation; //测试内置注解 public class TestAnnotation extends Object{ //@Override 重写的注解 @Override public String toString() { return super.toString(); } //@Deprecated 不推荐程序员使用,但是可以使用,或者存在更好的方式 @Deprecated public void test(){ System.out.println(); } //@SuppressWarnings 用来抑制编译时的警告信息 @SuppressWarnings("all") public void test02(){ String str;//定义变量但不使用,系统提示警告信息 } }
-
元注解
package com.java.annotation; import java.lang.annotation.*; //测试元注解 public class TestAnnotation02 { } //定义一个注解 //@Target 表示可以在哪些地方使用注解 @Target(value={ElementType.TYPE,ElementType.METHOD}) //@Retention 表示注解在什么地方有效 //Runtime > class > sources @Retention(value= RetentionPolicy.CLASS) //@Documented 表示是否将注解生成在JavaDoc文档中 @Documented //@Inherited 表示子类可以继承父类的注解 @Inherited @interface MyAnnotation{ }
-
自定义注解
package com.java.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; public class TestAnnotation03 { @MyAnnotation02(age=1)//注解可以显示赋值,如果没有默认值,必须给注解赋值 public void test(){ } @MyAnnotation03("a") public void test02(){ } } @Target({ElementType.TYPE,ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @interface MyAnnotation02{ //注解的参数:参数类型 + 参数名(); String name() default ""; int age(); int id() default -1;//默认值为-1,代表不存在 String[] str() default {"default"}; } @Target({ElementType.TYPE,ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @interface MyAnnotation03{ String value();//变量名为value时,在给注解赋值时可以省略参数名,直接赋值 }
反射
-
获得反射对象
package com.java.reflection; public class Test01 { public static void main(String[] args) throws ClassNotFoundException { //通过反射获取类的class对象 Class c1=Class.forName("com.java.reflection.User"); System.out.println(c1); Class c2=Class.forName("com.java.reflection.User"); Class c3=Class.forName("com.java.reflection.User"); Class c4=Class.forName("com.java.reflection.User"); //一个类在内存中只有一个class对象 //一个类被加载后,类的整个结构会被封装在class对象中 System.out.println(c2.hashCode()); System.out.println(c3.hashCode()); System.out.println(c4.hashCode()); } } //实体类:pojo,entity class User{ private String name; private int age; private int id; public User() { } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public int getId() { return id; } public void setId(int id) { this.id = id; } @Override public String toString() { return "User{" + "name='" + name + '\'' + ", age=" + age + ", id=" + id + '}'; } }
-
Class类的创建方式
package com.java.reflection; //测试class类的创建方式 public class Test02 { public static void main(String[] args) throws ClassNotFoundException { Person person=new Student(); System.out.println("这个人是:"+person.name); //方式一:通过对象获得 Class c1=person.getClass(); System.out.println(c1.hashCode()); //方式二:forName获得 Class c2=Class.forName("com.java.reflection.Student"); System.out.println(c2.hashCode()); //方式三:通过类名.class获得 Class<Student> c3=Student.class; System.out.println(c3.hashCode()); //方式四:基本内置类型的包装类都有一个Type属性 Class c4=Integer.TYPE; System.out.println(c4); //获得父类类型 Class c5=c1.getSuperclass(); System.out.println(c5); } } class Person{ public String name; public Person() { } public Person(String name) { this.name = name; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + '}'; } } class Student extends Person{ public Student(){ this.name="学生"; } } class Teacher extends Person{ public Teacher(){ this.name="老师"; } }
-
所有类型的Class类
package com.java.reflection; import java.lang.annotation.ElementType; //所有类型的class public class Test03 { public static void main(String[] args) { Class c1=Object.class; //类 Class c2=Comparable.class; //接口 Class c3=String[].class; //一维数组 Class c4=int[][].class; //二维数组 Class c5=Override.class; //注解 Class c6= ElementType.class; //枚举 Class c7=Integer.class; //基本数据类型 Class c8=void.class; //void Class c9=Class.class; //class System.out.println(c1); System.out.println(c2); System.out.println(c3); System.out.println(c4); System.out.println(c5); System.out.println(c6); System.out.println(c7); System.out.println(c8); System.out.println(c9); //只要元素类型与维度一致,就是同一个class int[] a=new int[10]; int[] b=new int[100]; System.out.println(a.getClass().hashCode()); System.out.println(b.getClass().hashCode()); } }
-
类的加载
package com.java.reflection; //测试类的加载 public class Test04 { public static void main(String[] args) { A a=new A(); System.out.println(a.m); /*1.类的加载,生成每个类对应的class对象 * 2.链接 * 3.初始化 * <clinit>(){ System.out.println("A类静态代码块初始化"); m=300; m=100; } m=100; */ } } class A{ static{ System.out.println("A类静态代码块初始化"); m=300; } static int m=100; public A() { System.out.println("A类无参构造初始化"); } }
-
类发生初始化的时间
package com.java.reflection; //类发生初始化的时间 public class Test05 { static{ System.out.println("Main类被加载"); } public static void main(String[] args) throws ClassNotFoundException { //1.主动引用 //Son son=new Son(); //反射也会产生注定引用 //Class.forName("com.java.reflection.Son"); //不会产生类的引用的方法 //System.out.println(Son.a); //Son[] son=new Son[5]; System.out.println(Son.B); } } class Father{ static int a=1; static{ System.out.println("父类被加载"); } } class Son extends Father{ static int b=10; static final int B=200; static{ System.out.println("子类被加载"); b=100; } }
-
类加载器
package com.java.reflection; public class Test06 { public static void main(String[] args) throws ClassNotFoundException { //获取系统类的加载器 ClassLoader classLoader=ClassLoader.getSystemClassLoader(); System.out.println(classLoader); //获取系统类加载器的父类加载器-->扩展类加载器 ClassLoader parent=classLoader.getParent(); System.out.println(parent); //获取扩展类加载器的父类加载器 ClassLoader parent2=parent.getParent(); System.out.println(parent2); //测试当前类的类加载器 ClassLoader classLoader1=Class.forName("com.java.reflection.Test06").getClassLoader(); System.out.println(classLoader1); //测试JDK内置类的类加载器 classLoader1=Class.forName("java.lang.Object").getClassLoader(); System.out.println(classLoader1); //获得系统类加载器可以加载是路径 System.out.println(System.getProperty("java.class.path")); /*E:\IdeaProjects\web-app\src\main\webapp\WEB-INF\lib; D:\Java\mysql-connector-java-8.0.22\mysql-connector-java-8.0.22.jar; E:\IdeaProjects\JavaSE\out\production\Base; E:\IdeaProjects\JavaSE\Bsae\src\com\lib\commons-io-2.8.0.jar */ } }
-
获取类的运行时结构
package com.java.reflection; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; public class Test07 { public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException { Class c1=Class.forName("com.java.reflection.User"); //获得类名 System.out.println(c1.getName()); System.out.println(c1.getSimpleName()); //获得类的属性 System.out.println("-----------------------"); Field[] fields=c1.getFields();//只能获取public属性 for(Field field:fields){ System.out.println(field); } System.out.println("-----------------------"); Field[] fields02=c1.getDeclaredFields();//获取所有属性 for(Field field:fields02){ System.out.println(field); } //获取指定属性 System.out.println("-----------------------"); Field field=c1.getDeclaredField("name"); System.out.println(field); //获取类的方法 System.out.println("-----------------------"); Method[] methods=c1.getMethods();//获取本类及父类的全部public方法 for (Method method:methods) { System.out.println("getMethods的方法:"+method); } Method[] methods02=c1.getDeclaredMethods();//获取本类的全部方法 for (Method method:methods02) { System.out.println("getDeclaredMethods的方法:"+method); } //获取指定方法 System.out.println("-----------------------"); Method getName=c1.getDeclaredMethod("getName", null); Method setName=c1.getDeclaredMethod("setName", String.class); System.out.println(getName); System.out.println(setName); //获取构造器 System.out.println("-----------------------"); Constructor[] constructors=c1.getConstructors(); for (Constructor constructor:constructors) { System.out.println(constructor); } Constructor[] constructors02=c1.getDeclaredConstructors(); for (Constructor constructor:constructors02) { System.out.println("***-->"+constructor); } //获取指定构造器 System.out.println("-----------------------"); Constructor constructor03=c1.getDeclaredConstructor(String.class, int.class, i nt.class); System.out.println(constructor03); } }
-
动态创建对象执行方
package com.java.reflection; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class Test08 { public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException { //获得class对象 Class c1=Class.forName("com.java.reflection.User"); //构造一个对象 System.out.print("构造一个对象:"); User user=(User) c1.newInstance(); System.out.println(user); //通过构造器创建对象 System.out.print("通过构造器创建对象:"); Constructor constructor=c1.getDeclaredConstructor(String.class,int.class,int.class); User user1=(User) constructor.newInstance("xuexi",002,23); System.out.println(user1); //通过反射调用普通方法 System.out.print("反射调用普通方法:"); User user2=(User) c1.newInstance(); //通过反射获取方法 Method setName=c1.getDeclaredMethod("setName", String.class); //invoke(对象,"方法值"): ** setName.invoke(user2,"芝士"); System.out.println(user2.getName()); //通过反射获取属性 System.out.print("反射获取属性:"); User user3=(User) c1.newInstance(); Field name = c1.getDeclaredField("name"); //不能直接操作私有属性,需要关闭程序的安全检测,属性或方法的setAccessible(true) name.setAccessible(true); name.set(user3,"圣灵"); System.out.println(user3.getName()); } }
-
性能对比分析
package com.java.reflection; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class Test09 { //普通方法调用 public static void test01(){ User user=new User(); long startTime=System.currentTimeMillis(); for (int i = 0; i < 10_0000_0000; i++) { user.getName(); } long endTime=System.currentTimeMillis(); System.out.println("普通方法执行10亿次:"+(endTime-startTime)+"ms"); } //反射方法调用 public static void test02() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { User user=new User(); Class c1=user.getClass(); Method getName=c1.getDeclaredMethod("getName",null); long startTime=System.currentTimeMillis(); for (int i = 0; i < 10_0000_0000; i++) { getName.invoke(user,null); } long endTime=System.currentTimeMillis(); System.out.println("反射方法执行10亿次:"+(endTime-startTime)+"ms"); } //反射方式调用 关闭检测 public static void test03() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { User user=new User(); Class c1=user.getClass(); Method getName=c1.getDeclaredMethod("getName",null); getName.setAccessible(true); long startTime=System.currentTimeMillis(); for (int i = 0; i < 10_0000_0000; i++) { getName.invoke(user,null); } long endTime=System.currentTimeMillis(); System.out.println("反射方法(关闭检测)执行10亿次:"+(endTime-startTime)+"ms"); } public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { test01(); test02(); test03(); } }
-
获取泛型信息
package com.java.reflection; import java.lang.reflect.MalformedParametersException; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.List; import java.util.Map; public class Test10 { public void test01(Map<String,User> map, List<User> list){ System.out.println("test01"); } public Map<String,User> test02(){ System.out.println("test02"); return null; } public static void main(String[] args) throws NoSuchMethodException { Method method=Test10.class.getMethod("test01", Map.class, List.class); Type[] genericParameterTypes =method.getGenericParameterTypes(); for (Type genericParameterType:genericParameterTypes) { System.out.println("*"+genericParameterType); if(genericParameterType instanceof ParameterizedType){ Type[] actualTypeArguments=((ParameterizedType) genericParameterType).getActualTypeArguments(); for (Type actualTypeArgument : actualTypeArguments) { System.out.println(actualTypeArgument); } } } System.out.println("------------------"); method=Test10.class.getMethod("test02",null); Type genericReturnType = method.getGenericReturnType(); if(genericReturnType instanceof ParameterizedType){ Type[] actualTypeArguments=((ParameterizedType) genericReturnType).getActualTypeArguments(); for (Type actualTypeArgument : actualTypeArguments) { System.out.println(actualTypeArgument); } } } }
-
获取注解信息
package com.java.reflection; import java.lang.annotation.*; import java.lang.reflect.Field; //练习:ORM-->对象关系映射 //利用注解和反射完成类和表结构的映射关系 public class Test11 { public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException { Class c1=Class.forName("com.java.reflection.Student01"); //通过反射获取注解 Annotation[] annotations = c1.getAnnotations(); for (Annotation annotation:annotations) { System.out.println(annotation); } //获得注解的value值 TableName tableName=(TableName) c1.getAnnotation(TableName.class); String value = tableName.value(); System.out.println(value); //获得类指定的注解 Field f=c1.getDeclaredField("name"); FieldInterface annotation=f.getAnnotation(FieldInterface.class); System.out.println(annotation.colName()); System.out.println(annotation.type()); System.out.println(annotation.length()); } } @TableName("db-student01") class Student01{ @FieldInterface(colName = "db-name",type = "varchar",length = 20) private String name; @FieldInterface(colName = "db-id",type = "int",length = 10) private int id; @FieldInterface(colName = "db-age",type = "int",length = 10) private int age; public Student01() { } public Student01(String name, int id, int age) { this.name = name; this.id = id; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "student{" + "name='" + name + '\'' + ", id=" + id + ", age=" + age + '}'; } } //类名的注解 @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @interface TableName{ String value(); } //属性的注解 @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) @interface FieldInterface{ String colName(); String type(); int length(); }