• 66.【注解与反射】


    (一)、注解

    1.什么是注解(Annoationation)

    1.Annotation的作用:
    (1).不是程序本身,可以对程序做出解释
    (2)."可以被其他程序(编译器)读取"
    2.Annotation的格式:
    (1).注解是以"@注释名"在代码中存在的,还可以添加一些参数值
    3.Annotation在哪里?
    (1).可以附加在package,class,method,field等上面,相当于给他们添加
    了额外的辅助信息,我们可以通过反射机制编程实现对这些元素数据的访问
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    2.内置注解

    @Override  :
    (1).定义在java.lang.Override 中,此注释只适用于修饰方法,表示一个方法
    声明打算"重写"超类中的另一个方法声明:
    (2).@ Deprecated: 定义在 java.lang,Deprecated中,此注释可以用于修饰方法
    ,属性,类,表示不鼓励程序员这样的元素,通常是因为它很危险或则存在更好的
    选择。
    (3).@SuppressWarnings :定义在java.lang.SuppressWarning中,用来抑制编译时
    的警告信息,
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    Override   重写的注解  (推翻)
    
    • 1

    在这里插入图片描述
    在这里插入图片描述

    Deprecated   不推荐程序员使用,但是可以使用,或则存在更好的方式 (已弃用)
    
    • 1

    在这里插入图片描述
    在这里插入图片描述

    SuppressWarnings("all")   镇压警告  (压制警告)
    
    • 1

    在这里插入图片描述
    在这里插入图片描述

    3.元注解

    元注解的作用就是"负责注解其他注解"Java定义了4个标准的meta-annotation类型,
    它们被用来提供对其他annotation类型作说明
    (1).@Target (目标)
    用于描述注解的适用范围(:被描述的注解可以用在什么地方)
    (2).@Retention (保持)
    表示需要在什么级别保存该注释信息,用于描述注解的生命周期
    (3).@Document (文档)
    说明该注解被包含在javadoc中
    (4).@inherited (继承)
    说明子类可以继承父类中的该注解 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    @Target (目标)  表示我们的注解可以用在哪些地方
    
    • 1

    在这里插入图片描述

    Retention  表示我们的注解在什么地方还有效?
    
    • 1
    Documented  表示是否将我们的注解生成在JavaDoc
    
    • 1
    Inherited子类可以继承父类的注解
    
    • 1

    在这里插入图片描述

    4.自定义注解

    1.自定义注解定义的方法:
    @interface自定义注解时,自动继承了java.lang.annoyation.Annotation的接口
    分析:
    (1).@interface用来声明一个注解
    eg: public @interface 注解名{定义内容}
    (2).其中的每一个方法实际上是声明了一个配置参数
    (3).方法的名称就是参数的名称
    (4).返回值类型就是参数的类型(返回值只能是基本类型, class String enum)
    (4).可以同过default来声明参数的默认值
    (6).如果只有一个参数成员,一般参数名为value
    (7).注解元素必须有值,我们定义注解元素时,经常使用空字符串,0作为默认值
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    public class Demo4 {
        //注解可以显示赋值,如果没有默认值,我们必须就给注解赋值
        @MyAnnotation(name = "吉士先生")
        public void test(){
    
        }
    
        @MyAnnotation2("李明")
        public void test2(){
    
        }
    }
    @Target(value = {ElementType.TYPE,ElementType.METHOD})   //适用范围
     @Retention(value = RetentionPolicy.RUNTIME)   //在什么时候还有效
    @interface MyAnnotation{
        //注解的参数:参数类型+参数名() 设置了默认值
        String name() ;
        int age() default 0;
        int id() default -1; //如果默认值为-1,代表不存在
        String [] string() default {"西部开源","北大"};
    }
    
    @Target({ElementType.METHOD,ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @interface MyAnnotation2{
        String value();   //如果只有一个值,可以写成value 这么就可以省略一个value
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    1.注解的参数:   参数类型+参数名()
    如果没有添加默认值,那么必须在上面的注解中进行赋值
    
    • 1
    • 2

    在这里插入图片描述

    2.注解的参数加一个默认值, 参数类型+参数名() default 默认值
    可以不用在注释上赋值了
    
    • 1
    • 2

    在这里插入图片描述

    3.如果注解中只有一个方法:可以把方法名定义成 value() ,那么就可以在
       注解上少写一个 value=;
    
    • 1
    • 2

    在这里插入图片描述

    (二)、反射机制(Reflection)

    5.反射概述

    1.静态语言:
    是一类与动态语言相对的,"运行的时候不可以改变的语言就是静态语言" java不是
    动态语言,但是java可以称之为"准动态语言" ----->反射机制
    eg:  java c c++
    2.动态语言:
    是一类在"运行时可以改变其结构的语言",比如新的代码、函数、对象可以引入。
    eg: JavaScript
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
     1.Reflection(反射)是java被视为动态语言的关键,反射机制允许程序在执行
    期借助于Reflection API获取任何类的内部信息,并且能直接操作任意对象的
    内部属性及方法.
    "class c=Class.forName("java.lang.String")"
    2.加载完类之后,在堆内存的方法区中就产生了一个class类型的对象(一个类只有
    一个class对象),这个对象就包含了完整的类的结构信息。我们可以通过这个对象
    看到类的结构。"这个对象就像一面镜子,通过这个镜子看到类的结构,我们称之为"
    "反射"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    java反射机制提供的功能
    1.在运行时判断任意一个对象所属的类
    2.在运行时构造任意一个类的对象
    3.在运行的时候判断任意一个类的所具有的成员变量和方法
    4.在运行时获取泛型信息
    5.在运行时调用任意一个对象的成员变量和方法
    6.在运行时处理注解
    7.生成动态代理
    .....
    优点:
    1.可以实现动态创建对象和编译,体现出很大的灵活性
    缺点:
    对性能有影响:使用反射基本上是一种解释操作。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    6.获得反射对象

    通过反射获取对象:
    1.
    "class c=Class.forName("java.lang.String")"
    "并且对象有且只有一个 (就是只有一个值)"
    一个类被加载后,类的整个结构都会被封装在class对象中
    2.
    Class c=person.getClass()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    package com.Kuang.reflectiom;
    public class Demo5 {
        public static void main(String[] args) throws ClassCastException {
            //通过反射获取类的class对象
            try {
                Class aClass_one = Class.forName("com.Kuang.reflectiom.User");
                System.out.println(aClass_one);
    
                //一个类在内存中只有一个class对象
                //一个类被加载后,类的整个结构都会被封装在class对象中
    
                Class aClass_2 = Class.forName("com.Kuang.reflectiom.User");
                Class aClass_3 = Class.forName("com.Kuang.reflectiom.User");
                Class aClass_4 = Class.forName("com.Kuang.reflectiom.User");
                System.out.println(aClass_2.hashCode());
                System.out.println(aClass_3.hashCode());
                System.out.println(aClass_4.hashCode());
    
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
    }
    //实体类 pojo,entity
    class User{
        private String name;
        private int id;
        private int age;
    
        public User() {
        }
    
        public User(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;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62

    在这里插入图片描述

    反射:  通过class对象得出来类
    非反射:   通过类得出来对象
    
    • 1
    • 2

    7.得到Class类的方法

    1.对象通过反射可以得到的信息:
    (1).类的属性
    (2).方法 
    (3).构造器。
    2.详解:
    (1).class 本身也是一个类
    (2).class 对象只能由系统建立对象
    (3).一个加载的类在jvm中只会有一个class实列
    (4).每个类的实列都会记得自己是由哪个class实列所生成的
    (5).通过class可以完整的得到一个类中的所有被加载的结构
    (6).class是reflection的根源,针对任何你想动态加载、运行的类,唯有先
    获得相应的class对象
    (7).一个class对象对应的是一个加载到jvm中的一个class文件
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    方式1: 通过对象获得
            Class c1=person.getClass();
    方式2: forName获得 
    		Class<?> aClass = Class.forName("com.Kuang.reflectiom.Student"); 
    方式3:通过类名.class获得
            Class studentClass = Student.class;      
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    package com.Kuang.reflectiom;
    
    public class Demo6 {
        public static void main(String[] args) {
            Person person=new Student();
            System.out.println("这个人是:"+person.name);
    
            //方式1: 通过对象获得
            Class c1=person.getClass();
            System.out.println(c1.hashCode());
            //方式2: forName获得
            try {
                Class<?> aClass = Class.forName("com.Kuang.reflectiom.Student");
                System.out.println(aClass.hashCode());
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
    
            //方式3:通过类名.class获得
            Class studentClass = Student.class;
            System.out.println(studentClass.hashCode());
    
    
    
            Class superclass = c1.getSuperclass();  //得到父类
            System.out.println(superclass);
        }
    }
    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="李老师";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55

    在这里插入图片描述

    8.所有类型都有class

    记住在一个程序中只有一个class对象,就是说一个类型不管数据怎么变化
    class对象是不会变的。
    
    • 1
    • 2
    package com.Kuang.reflectiom;
    
    import java.lang.annotation.ElementType;
    
    public class Demo7 {
        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;   //空型
            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);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    在这里插入图片描述

    9.类加载内存分析

    java的内存分析:
    在这里插入图片描述

    类的加载过程:
    
    • 1

    在这里插入图片描述

    类的加载与classLoader的理解
    
    • 1

    在这里插入图片描述

    package com.Kuang.reflectiom;
    
    public class Demo8 {
        public static void main(String[] args) {
            A s=new A();
            System.out.println(A.m);
        }
    }
    class  A{
        static {
            System.out.println("A 类静态代码初始化");
            m=300;
        }
        static int m=100;
        public A(){
            System.out.println("A 类的无参构造初始化");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    在这里插入图片描述

    10.分析类初始化

    什么时候会发生类初始化?
    1.类的主动引用(一定会发生类的初始化)
    (1).当虚拟机启动,先初始化main方法所在的类
    (2).new 一个类的对象
    (3).调用类的静态成员(除了final常量)和静态方法
    (4).使用reflect 的方法进行反射调用
    (5).当初始化一个类,如果其父类没有被初始化,则先会初始化它的父类
    "(意思就是:当我们new子类的对象的时候,父类的构造器会被先初始化)"
    2.类的被动引用(不会发生类的初始化)
    (1).当访问一个静态域时,只有真正声明这个域得类才会被初始化,
    (2).通过数组定义类引用,不会触发此类的初始化
    (3).引用常量不会触发此类的初始化
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    当初始化一个类,如果其父类没有被初始化,则先会初始化它的父类
    
    • 1
    package com.Kuang.reflectiom;
    
    public class Demo9 {
        static {
            System.out.println("main类被加载!");
        }
    
        public static void main(String[] args)  {
            //Son son=new Son();
            //利用反射的方法
            try {
                Class.forName("com.Kuang.reflectiom.Son");
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
    
        }
    }
    class Father{
        static int b=2;
        static {
            System.out.println("父类被加载");
        }
    }
    class Son extends Father{
        static {
            System.out.println("子类被加载");
            m=300;
        }
        static int m=100;
        static final int M=1;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    在这里插入图片描述

    11.类加载器

    1.类加载器的作用:class文件字节码内容加载到内存中,并将这些静态数据转换成方法去的运行时
    数据结构,然后在堆中生成一个戴白哦这个类的class对象,作为方法区中类数据
    的访问入口
    
    2.java文件过程:
    
    java文件--->java编译器---->字节码(.class文件)---->类装载器
    ----->字节码校验器----->解释器----->操作系统平台
    
    3.类加载器的作用:
    类加载器的作用是用来把类(class)装载进内存的,jvm规范定义了如下的加载器:
    
    (1).引导类加载器: jvm自带的加载器,"负责java平台核心库"。该加载器无法直
    接获取.
    
    (2).扩展类加载器: 负责jre/lib/ext目录库下的jar包
    
    (3).系统加载器:负责classpath或path所指目录下的jar包
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    package com.Kuang.reflectiom;
    
    public class Demo10 {
        public static void main(String[] args) {
            //获取系统类的加载器
            ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
            System.out.println(systemClassLoader);
    
            //获取系统类的加载器的父类加载器---->扩展类加载器
            ClassLoader parent = systemClassLoader.getParent();
            System.out.println(parent);
    
            //获取扩展类加载器的父类  ---->跟加载器
            ClassLoader parent1 = parent.getParent();
            System.out.println(parent1);
    
            //当前类是那个加载器加载的?
            try {
                ClassLoader classLoader = Class.forName("com.Kuang.reflectiom.Demo7").getClassLoader();
                System.out.println(classLoader);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    在这里插入图片描述

    12.获取类运行时类的完整结构

    1.获得包名+类名
    System.out.println(aClass.getName());  
    2.获得类名
    System.out.println(aClass.getSimpleName());  
    3.获得类的全部属性
    aClass.getDeclaredFields()
    4.获得类的public属性
    aClass.getField();
    5.获得本类的及父类的全部public方法
    aClass.getMethods();
    6.获得类的所有方法
    aClass.getDeclaredMethods();
    7.获得类的指定方法:
    aClass.getMethod();
    7.获得全部构造器:
    aClass.getDeclaredConstructors();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    package com.Kuang.reflectiom;
    
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    
    public class Demo11 {
        public static void main(String[] args) {
            try {
                Class<?> aClass = Class.forName("com.Kuang.reflectiom.User");
    
                //获得类的名字
                System.out.println(aClass.getName());  //获得包名+类名
                System.out.println(aClass.getSimpleName());  //获得类名
    
                //获得类的属性
                Field[] fields=aClass.getDeclaredFields();
                for (Field field : fields) {
                    System.out.println(field);
                }
                System.out.println("------------------");
                //获得类的方法
                Method[] declaredMethods = aClass.getDeclaredMethods();
                for (Method declaredMethod : declaredMethods) {
                    System.out.println(declaredMethod);
                }
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    在这里插入图片描述

    13.动态创建对象执行方法

    1.
    创建类的对象: 调用class对象的newInstance()方法
    (1).类必须有一个无参数的构造器
    (2).类的构造器的访问权限需要足够
    eg: User user = (User) aClass.newInstance(); 构造一个对象----->本质上调用了无参
    
    2.难道没有无参的构造器就不能创建对象了么?
    (1).只要在操作的时候明确的调用类中的构造器,并将参数传递进去之后,
    才可以实列化.                             
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    2.没有无参构造器的解决办法: 
    这里User没有添加: 无参
    
    • 1
    • 2
    package com.Kuang.reflectiom;
    public class Demo5 {
        public static void main(String[] args) throws ClassCastException {
            //通过反射获取类的class对象
            try {
                Class aClass_one = Class.forName("com.Kuang.reflectiom.User");
                System.out.println(aClass_one);
    
                //一个类在内存中只有一个class对象
                //一个类被加载后,类的整个结构都会被封装在class对象中
    
                Class aClass_2 = Class.forName("com.Kuang.reflectiom.User");
                Class aClass_3 = Class.forName("com.Kuang.reflectiom.User");
                Class aClass_4 = Class.forName("com.Kuang.reflectiom.User");
                System.out.println(aClass_2.hashCode());
                System.out.println(aClass_3.hashCode());
                System.out.println(aClass_4.hashCode());
    
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
    }
    //实体类 pojo,entity
    class User{
       private String name;
        private int id;
        private int age;
    
        public User(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 "User{" +
                    "name='" + name + '\'' +
                    ", id=" + id +
                    ", age=" + age +
                    '}';
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    package com.Kuang.reflectiom;
    
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    
    public class Demo12 {
     public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
    //获得class对象
    Class aClass = Class.forName("com.Kuang.reflectiom.User");
    //获得构造器 ,通过构造器创建对象----->调用了有参
    Constructor declaredConstructor = aClass.getDeclaredConstructor(String.class, int.class, int.class);
    User user2 = (User)declaredConstructor.newInstance("吉士先生", 001, 18);
    System.out.println(user2);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    1.执行方法:
    setAccessible(true);   关闭权限检测
    invoke(user3,"吉士先生")  invoke: 激活的意思  (对象,"方法的值")
    
    • 1
    • 2
    • 3
    package com.Kuang.reflectiom;
    
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    
    public class Demo12 {
        public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
    
                //获得class对象
                Class aClass = Class.forName("com.Kuang.reflectiom.User");
    
    
               //构造一个对象----->调用了无参
                User user = (User) aClass.newInstance();
                 System.out.println(user);
    
                //获得构造器 ,通过构造器创建对象----->调用了有参
           Constructor declaredConstructor = aClass.getDeclaredConstructor(String.class, int.class, int.class);
           User user2 = (User)declaredConstructor.newInstance("吉士先生", 001, 18);
           System.out.println(user2);
    
    
            //通过反射调用方法
            User user3=(User) aClass.newInstance();
            Method setName = aClass.getDeclaredMethod("setName", String.class);
            //invoke: 激活的意思  (对象,"方法的值")
    
            setName.invoke(user3,"吉士先生");
            System.out.println(user3.getName());
    
            //通过反射操作属性
            User user4=(User) aClass.newInstance();
            Field name = aClass.getDeclaredField("name");
    
            name.setAccessible(true);  //关闭权限检测,如果不关闭,那么私有属性我们就访问不了
            name.set(user4,"吉士先生2");
            System.out.println(user4.getName());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    在这里插入图片描述

    14.获取泛型信息

    1.java采用泛型擦除的机制来引入泛型,java中的泛型仅仅是给编译器javac使用的,
    确保数据的安全性和免去强制类型转换问题,但是,一旦编译完成,所有和泛型有关
    的类型全部擦除。
    2.为了通过反射操作这些类型,java新增了parameterizedTpye,GenericType,
    TypeVaiableWildcardType几种类型来代表不能被归一到class类中的类型但是
    又和原始类型齐名的类型
    (1).parameterizedTpye: 表示一种参数化类型
    (2).GenericType: 表示一种元素类型是参数化类型或者类型变量的数组类型
    (3).TypeVaiable: 是各种类型变量的公共父接口
    (4).WildcardType: 代表一种通配符类型表达式。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    15.反射操作注解

    package com.Kuang.reflectiom;
    
    import java.lang.annotation.*;
    import java.lang.reflect.Field;
    
    public class Demo13 {
        public static void main(String[] args) throws NoSuchFieldException {
            try {
                Class<?> aClass = Class.forName("com.Kuang.reflectiom.Student2");
    
                //通过反射获得注解
                Annotation[] annotations = aClass.getAnnotations();
                for (Annotation annotation : annotations) {
                    System.out.println(annotation);
                }
    
                //获得注解的value的值
                TableKuang tableKuang = (TableKuang) aClass.getAnnotation(TableKuang.class);
                String value = tableKuang.value();
                System.out.println(value);
    
                //获得类指定的注解
                Field name = aClass.getDeclaredField("name");
                FieldKuang annotation = name.getAnnotation(FieldKuang.class);
                System.out.println(annotation.columname());
                System.out.println(annotation.type());
                System.out.println(annotation.length());
    
    
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
    
    }
    @TableKuang("db_student")
    class Student2{
        @FieldKuang(columname = "db_id",type = "int",length = 10)
        private int id;
        @FieldKuang(columname = "db_age",type = "int",length = 10)
        private int age;
        @FieldKuang(columname = "db_name",type = "Varchar",length = 10)
        private String name;
    
        public Student2() {
        }
    
        public Student2(int id, int age, String name) {
            this.id = id;
            this.age = age;
            this.name = name;
        }
    
        @Override
        public String toString() {
            return "com.Kuang.reflectiom.Student2{" +
                    "id=" + id +
                    ", age=" + age +
                    ", 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;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }
    
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @interface TableKuang{
        String value();
    }
    
    @Target(ElementType.FIELD)
    @Retention(RetentionPolicy.RUNTIME)
    @interface FieldKuang{
        String columname();
        String type();
        int length();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
  • 相关阅读:
    【Linux】~ 如何将本地文件(windows)复制(传输)到虚拟机中
    3 开源鸿蒙OpenHarmony4.1源码下载、编译,生成OHOS_Image可执行文件的最简易流程
    【每日力扣】41. 缺失的第一个正数 238. 除自身以外数组的乘积 189. 轮转数组
    Web前端快速开发 Bootstrap 响应式UI框架
    C# 连接 MySQL 数据库
    基本数据结构与算法JavaAPI【1】--线性表篇
    CentOS7环境下定时任务执行不成功的排查
    Docker load 大镜像(17G) 报错no space left on device
    每日三题 7.23
    分析:「羊了个羊」为什么能在超级App出圈
  • 原文地址:https://blog.csdn.net/qq_69683957/article/details/127433309