欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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();
    }