Java SE(注解与反射)

注解与反射

注解

  • 内置注解

    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.初始化
            *     (){
                        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();
    }
    

你可能感兴趣的:(自学,学习,反射,java,class)