zoukankan      html  css  js  c++  java
  • 注解 与 反射

    注解Annotation

    在这里插入图片描述

    内置注解

    @override:定义重写声明

    @Deprecated:表示不鼓励使用

    @SuppressWarnings:抑制警告信息

    使用需要参数 参数已经定义好了 选择使用即可

    1.@SuppressWarnings(“all”)

    2.@SuppressWarnings(“unchecked”)

    3.@SuppressWarnings(value={“unchecked”,“deprecation”})

    package First;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class Demo01  extends  Object{
        //@Override 重写的注解
        @Override
        public String toString() {
            return "Demo01{}";
        }
        //@Deprecated 不推荐程序员使用 但是可以使用 一般有更好的方法
        @Deprecated
        public  static void test(){
            System.out.println("Deprecated");
        }
        @SuppressWarnings("all") //下方未使用的警告不再提示
        public  static void test02(){
            List list = new ArrayList();
        }
    
        public static void main(String[] args) {
            test();
        }
    }
    12345678910111213141516171819202122232425
    

    元注解 meta-annotation

    在这里插入图片描述

    自定义注解 @interface

    package First;
    
    import java.lang.annotation.*;
    
    //@MyAnnotation 定义注解目标为方法 故不可以使用
    public class Test02 {
    
    
            @MyAnnotation//定义注解目标为方法 故可以使用
            public void test(){
        }
    }
    
    //@Target 表示我们的注解可以用在那些地方 值为ElementType
    @Target(value = ElementType.METHOD)
    
    //@Retention 表示我们的注解可以用在哪些地方
    //runtime运行时>class>sourcejava
    @Retention(value = RetentionPolicy.RUNTIME)
    //@Documented 表示是否我们的注解生成在JAVAdoc中
    @Documented
    @Inherited //表示子类可以继承注解
    
    @interface MyAnnotation{}
    123456789101112131415161718192021222324
    

    在这里插入图片描述

    package First;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    public class Test03 {
        @MyAnnotation03("当场注解")
        @MyAnnotation02(age = 10,name = "alin")//参数顺序可以调换 必许带参数名
        public void test03(){
            
        }
        
    }
    
    @Target({ElementType.TYPE,ElementType.METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    @interface MyAnnotation02{
        //参数定义 参数类型 参数名()
        String name() default "";//default 进行默认赋值
        int age() default 0;
        int id()  default -1;//表示不存在
        String[] students() default {"青岛大学","南京邮电大学" };
    }
    @Target({ElementType.TYPE,ElementType.METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    @interface  MyAnnotation03{
        String value();//一个参数时 最好命名为value 命名为value时 在使用此注解时可以不加value
    }
    

    反射Reflection

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

    在这里插入图片描述

    package Reflection;
    
    public class Demo01 {
        public static void main(String[] args) throws ClassNotFoundException {
            //通过反射获取类的Class类型
            Class  c1 = Class.forName("Reflection.User");
            Class  c2 = Class.forName("Reflection.User");
            Class  c3 = Class.forName("Reflection.User");
            //一个类只有一个Class对象 故c1 c2 c3 hashcode相同
            //一个类被加载之后 类的整个结构都会被封装在Class对象中
            System.out.println(c1.hashCode());
            System.out.println(c1.hashCode());
            System.out.println(c1.hashCode());
        }
    }
    
    //实体类 pojo entity
    class User{
        String name;
        int age;
        int id;
    
        public User() {
        }
    
        public User(String name, int age, int id) {
            this.name = name;
            this.age = age;
            this.id = id;
        }
    }
    
    

    在这里插入图片描述

    Class类

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

    获得class的方法

    package Reflection;
    
    
    
    public class Demo02 {
        public static void main(String[] args) throws ClassNotFoundException {
            Person person = new Student();
            System.out.println("这个人是:"+person.name);
            //通过对象获得class
            Class c1 = person.getClass();
            System.out.println(c1.hashCode());
            //通过类获得class
            Class c2 = Student.class;
            System.out.println(c2.hashCode());
            //通过forname获得class
            Class c3 = Class.forName("Reflection.Student");
            System.out.println(c3.hashCode());
            //通过内置函数的包装类获得class
            Class c4 = Integer.TYPE;
            System.out.println(c4);
            //获得父类的class
            Class c5 = c1.getSuperclass();
            System.out.println(c5);
    
        }
    }
    
    
    class Person{
        public String name;
    
        public Person() {
        }
    
        public Person(String name) {
            this.name = name;
        }
    }
    class Student extends Person{
        public Student() {
            this.name="学生";
        }
    }
    class Teacher extends  Person{
        public Teacher() {
            this.name = "教师";
        }
    }
    

    有Class对象

    在这里插入图片描述

    package Reflection;
    
    import java.net.InterfaceAddress;
    import java.util.Enumeration;
    
    //拥有class对象的类型
    public class Demo03 {
        public static void main(String[] args) {
            Class c1 = Object.class;
            Class c2 = Comparable.class;
            Class c3 = String[].class;
            Class c4 = int[][].class;
            Class c5 = Enumeration.class;
            Class c6 = Integer.class;
            Class c7 = Override.class;
            Class c8 = Void.class;
            Class c9 = void.class;
            Class c10 = 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 );
            System.out.println(c10);
    
            //当类型和维数相同时只有一个class对象
            int[] a = new int[10];
            int[] b = new int[100];
            System.out.println(a.getClass().hashCode());
            System.out.println(b.getClass().hashCode());
    
        }
    }
    
    输出:
    class java.lang.Object
    interface java.lang.Comparable
    class [Ljava.lang.String;
    class [[I
    interface java.util.Enumeration
    class java.lang.Integer
    interface java.lang.Override
    class java.lang.Void
    void
    class java.lang.Class
    

    加载类class

    package Reflection;
    
    public class Demo04 {
        public static void main(String[] args) {
            A a = new A();
            System.out.println(A.m);
    
        }
    }
    /*
        1.加载到内存,会产生一个类对应Class对象在堆区
        2.链接,在栈中产生 main m=0;
        3.初始化
        <clinit>{
        System.out.println("A类静态代码块初始化");
            m=300;
            m=100;  静态 按顺序执行的 若把 int m =100 ;放上面 则为300;
            }
    
     */
    
    class A{
        static {
            System.out.println("A类静态代码块初始化");
            m=300;
        }
        /*
        m=300;
        m=100; 覆盖上方300
         */
        static int m =100;
    
        public A() {
            System.out.println("A类的无参构造器");
        }
    }
    
    
    输出:
    A类静态代码块初始化
    A类的无参构造器
    100
    
    

    类的初始化
    在这里插入图片描述

    package Reflection;
    
    public class Demo05 {
        static {
            System.out.println("Main类被调用了");
        }
    
        public static void main(String[] args) throws ClassNotFoundException {
            //1.创建对象 若父类没初始化 先初始化父类
            //Son son = new Son();
            /*
            Main类被调用了
            父类被加载
            子类被加载了
            100
             */
            //2.通过反射
            //Class c1 = Class.forName("Reflection.Son");//Main类被调用  父类被加载  子类被加载了
            //3.调用静态
            //System.out.println(Son.m);//Main类被调用了 父类被加载 子类被加载了 200
    
            //被动引用
            //子类引用父类静态变量
            //System.out.println(Son.b);//Main类被调用了 父类被加载 100
            //数组定义类引用,不触发初始化
            //Son[] a1 = new Son[5]; Main类被调用了
            //引用常量,不触发初始化
            //System.out.println(Son.M);      Main类被调用了 1
    
        }
    }
    class Father{
        static {
            System.out.println("父类被加载");
            //int b=10;
        }
        static int b =100;
    }
    class Son extends Father{
        static {
            System.out.println("子类被加载了");
            m=300;
        }
        static int m=200;
        static final int M=1;
    }
    

    类加载器

    在这里插入图片描述

    双亲委派机制: 当某个类加载器需要加载某个.class文件时,它首先把这个任务委托给他的上级类加载器,递归这个操作,如果上级的类加载器没有加载,自己才会去加载这个类。

    img

    动态创建对象

    invoke setAccessible

    在这里插入图片描述

    package Reflection;
    
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    
    public class Demo08 {
        public static void main(String[] args) throws Exception {
            Class c1 = Class.forName("Reflection.User");
            //反射得到对象
            //User user = (User) c1.newInstance();//调用无参构造器 new一个对象  高版本此方法已过时 使用c1.getDeclaredConstructor().newInstance()
            //System.out.println(user);
            //使用构造器
            //Constructor constructor = c1.getDeclaredConstructor(String.class, int.class, int.class);
            //User user1=(User)constructor.newInstance("小明",18,001);
            //System.out.println(user1);
            //反射调用普通方法
            User user= (User) c1.newInstance();
            //通过反射获取一个方法
            Method setName = c1.getMethod("setName",String.class);
            //invoke 激活 (对象,"方法的值")
            setName.invoke(user,"ck");
            System.out.println(user.getName());
            //通过反射操作属性
            System.out.println("==========");
            User user1=(User)c1.newInstance();
            Field name = c1.getDeclaredField("name");
            name.setAccessible(true);//关闭安全检测 对私有属性可以操作
            name.set(user1,"小小");
            System.out.println(user1.getName());
            
        }
    }
    ck
    ==========
    小小
    123456789101112131415161718192021222324252627282930313233343536
    

    性能检测

    package Reflection;
    
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    
    public class Demo09 {
        //普通调用
        public static void test01(){
            User user = new User();
            long startTime = System.currentTimeMillis();
            for (int i = 0; i < 1000000000; 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 < 1000000000; 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 < 1000000000; 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();
        }
    
    
    }
    普通调用10亿次耗费4ms
    反射调用10亿次耗费2063ms
    关闭安全检测后反射调用10亿次耗费1265ms
    

    可以看出 反射的方式调用 耗时较久

    通过反射获得注解

    package Reflection;
    
    import java.lang.annotation.*;
    import java.lang.reflect.Field;
    
    public class Demo11 {
        public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
            Class c1 = Class.forName("Reflection.Student2");
            //获得类的注解
            Annotation[] annotations = c1.getAnnotations();
            for (Annotation annotation : annotations) {
                System.out.println(annotation);
            }
            //获得注解的值
            Typekang typekang =(Typekang) c1.getAnnotation(Typekang.class);
            String value =typekang.value();
            System.out.println(value);
            //获得指定注解的值
            Field field = c1.getDeclaredField("name");
            Fieldkang fieldkang =  field.getAnnotation(Fieldkang.class);
            System.out.println(fieldkang.columname());
            System.out.println(fieldkang.type());
            System.out.println(fieldkang.length());
        }
    
    }
    
    @Typekang("db_Student")
    class Student2{
        @Fieldkang(columname = "db_name",type = "varchar",length = 10)
        private String name;
        @Fieldkang(columname = "db_age",type = "int",length = 10)
        private int age;
        @Fieldkang(columname = "db_id",type = "int",length = 10)
        private  int id;
    
        public Student2(String name, int age, int id) {
            this.name = name;
            this.age = age;
            this.id = id;
        }
    
        public Student2() {
        }
    }
    
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @interface  Typekang{
          String value();
    }
    @Target(ElementType.FIELD)
    @Retention(RetentionPolicy.RUNTIME)
    @interface Fieldkang{
        String columname();
        String type();
        int length();
    }
    
    
    
    @Reflection.Typekang(value=db_Student)
    db_Student
    db_name
    varchar
    10
    
  • 相关阅读:
    Android-WebView路由登录192.168.1.1
    Win7 & VirtualBox虚拟Ubuntu 本地虚拟机之间文件共享
    Android 简单的JNI编程
    Android ActionBar简单使用
    多个APK之间简单数据共享
    js代码移动Div 移动平台与PC平台
    JavaScript面向对象
    《SSO CAS单点系列》之 APP原生应用如何访问CAS认证中心
    insh.exe:*** Couldn't reserve space for cygwin's heap,Win32 error 0
    解决:SSM框架中普通类调用Service的问题 (转)
  • 原文地址:https://www.cnblogs.com/xiaxiaopi/p/14442176.html
Copyright © 2011-2022 走看看