Java 注解与反射


本文是自己 看视频的 总结 一些东西不是那么准确

注解

注解解释:

就是 @ 符号 + 名称

常见的注解:

1: 生成文档的注解 比如 @return这些:

在这里插入图片描述

2: jdk 的三个基本注解:

在这里插入图片描述
@Override : 重写父类方法
@Deprecated :用于表示所修饰的类或者方法已过时 (就是 加条横线)
@SuppressWarnings(): 抑制编译器警告

自定义注解:

在这里插入图片描述

在这里插入图片描述

JDK 的元注解

就是修饰其他的注解的
@Target 管 注解的作用位置 (类 方法)
在这里插入图片描述
@Retention 管生命周期的
在这里插入图片描述

@Documented
@Inherited
在这里插入图片描述

反射

反射的概述:

在这里插入图片描述

反射主要的api

在这里插入图片描述

Class四种实现方法:

在这里插入图片描述

//方式一: 调用类的属性 .class
        Class clazz = Person.class;
        System.out.println(clazz);

        //方式二: 调用类的方法  getclass
        Person p=new Person();
        Class  clazz2 = p.getClass();
        System.out.println(clazz2);

        //方式三 调用Calss的静态方法  forname(string  classs path)
        Class clazz3=null;
        try {
            clazz3 = Class.forName("com.company.day5.Person");
            System.out.println(clazz3);
        } catch (ClassNotFoundException e) {
            System.out.println("没找到该类的路径");
        }

        //方式四: 使用类的加载器 : ClassLoader (了解)
        Class clazz4=null;
        ClassLoader loader = ClassTest.class.getClassLoader();
        try {
            clazz4 = loader.loadClass("com.company.day5.Person");
            System.out.println(clazz4);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        System.out.println(clazz==clazz2);
        System.out.println(clazz==clazz3);
        System.out.println(clazz==clazz4);

在这里插入图片描述

最后 他们获取到的类 对应的地址 是一样的。

补充

可以获取到class 实列的类:
在这里插入图片描述

读取properties 文件:

注意 使用了 classloader 如果properties 再src 以外的目录下 是读不到的(我百度的结果)

Properties properties=new Properties();
        //不用classloader
        FileInputStream input=new FileInputStream("src/test.properties");
        properties.load(input);
        System.out.println(properties.getProperty("name"));
        System.out.println(properties.getProperty("age"));

        //使用了classloader:
//        ClassLoader loader = ClassTest.class.getClassLoader();
//        InputStream is = loader.getResourceAsStream("test.properties");
//        properties.load(is);
//        System.out.println(properties.getProperty("name"));
//        System.out.println(properties.getProperty("age"));


利用反射创建对象和获取方法的结构等

创建对象:
 public void test3() throws IllegalAccessException, InstantiationException {
        Class<Person> clazz = Person.class;
        //利用空参构造器 进行获取
        Person person = clazz.newInstance();
        System.out.println(person);
    }
获取方法的结构等(了解)

获取属性:

 @Test
    public void test3() throws IllegalAccessException, InstantiationException {
        Class<Person> clazz = Person.class;
        //获取属性结构
        //getFields():获取当前运行时类及其父类中声明为public访问权限的属性
        Field[] fields = clazz.getFields();
        for (Field field : fields) {
            System.out.println(field);
        }
        System.out.println("++++++++++");

        //getDeclaredFields():获取当前运行时类中声明的所有属性。(不包含父类中声明的属性)
        Field[] declaredFields = clazz.getDeclaredFields();
        for(Field f : declaredFields){
            System.out.println(f);
        }


    }
 //权限修饰符  数据类型 变量名
    @Test
    public void test2(){
        Class clazz = Person.class;
        Field[] declaredFields = clazz.getDeclaredFields();
        for(Field f : declaredFields){
            //1.权限修饰符
            int modifier = f.getModifiers();
            System.out.print(Modifier.toString(modifier) + "\t");

            //2.数据类型
            Class type = f.getType();
            System.out.print(type.getName() + "\t");

            //3.变量名
            String fName = f.getName();
            System.out.print(fName);

            System.out.println();
        }
获取方法:
 Class clazz = Person.class;

        //getMethods():获取当前运行时类及其所有父类中声明为public权限的方法
        Method[] methods = clazz.getMethods();
        for(Method m : methods){
            System.out.println(m);
        }
        System.out.println();
        //getDeclaredMethods():获取当前运行时类中声明的所有方法。(不包含父类中声明的方法)
        Method[] declaredMethods = clazz.getDeclaredMethods();
        for(Method m : declaredMethods){
            System.out.println(m);
        }



 Class clazz = Person.class;
        Method[] declaredMethods = clazz.getDeclaredMethods();
        for(Method m : declaredMethods){
            //1.获取方法声明的注解
            Annotation[] annos = m.getAnnotations();
            for(Annotation a : annos){
                System.out.println(a);
            }

            //2.权限修饰符
            System.out.print(Modifier.toString(m.getModifiers()) + "\t");

            //3.返回值类型
            System.out.print(m.getReturnType().getName() + "\t");

            //4.方法名
            System.out.print(m.getName());
            System.out.print("(");
            //5.形参列表
            Class[] parameterTypes = m.getParameterTypes();
            if(!(parameterTypes == null && parameterTypes.length == 0)){
                for(int i = 0;i < parameterTypes.length;i++){

                    if(i == parameterTypes.length - 1){
                        System.out.print(parameterTypes[i].getName() + " args_" + i);
                        break;
                    }

                    System.out.print(parameterTypes[i].getName() + " args_" + i + ",");
                }
            }

            System.out.print(")");

            //6.抛出的异常
            Class[] exceptionTypes = m.getExceptionTypes();
            if(exceptionTypes.length > 0){
                System.out.print("throws ");
                for(int i = 0;i < exceptionTypes.length;i++){
                    if(i == exceptionTypes.length - 1){
                        System.out.print(exceptionTypes[i].getName());
                        break;
                    }

                    System.out.print(exceptionTypes[i].getName() + ",");
                }
            }


            System.out.println();
        }


获取构造器信息:
Class clazz = Person.class;
        //getConstructors():获取当前运行时类中声明为public的构造器
        Constructor[] constructors = clazz.getConstructors();
        for(Constructor c : constructors){
            System.out.println(c);
        }

        System.out.println();
        //getDeclaredConstructors():获取当前运行时类中声明的所有的构造器
        Constructor[] declaredConstructors = clazz.getDeclaredConstructors();
        for(Constructor c : declaredConstructors){
            System.out.println(c);
        }
操作运行时类的变量和方法:
变量:
 Class clazz = Person.class;

        //创建运行时类的对象
        Person p = (Person) clazz.newInstance();

        //1. getDeclaredField(String fieldName):获取运行时类中指定变量名的属性
        Field name = clazz.getDeclaredField("name");

        //2.保证当前属性是可访问的
        name.setAccessible(true);
        //3.获取、设置指定对象的此属性值
        name.set(p,"Tom");

        System.out.println(name.get(p));
方法:
 Class clazz = Person.class;

        //创建运行时类的对象
        Person p = (Person) clazz.newInstance();

        /*
        1.获取指定的某个方法
        getDeclaredMethod():参数1 :指明获取的方法的名称  参数2:指明获取的方法的形参列表
         */
        Method show = clazz.getDeclaredMethod("show", String.class);
        //2.保证当前方法是可访问的
        show.setAccessible(true);

        /*
        3. 调用方法的invoke():参数1:方法的调用者  参数2:给方法形参赋值的实参
        invoke()的返回值即为对应类中调用的方法的返回值。
         */
        Object returnValue = show.invoke(p,"CHN"); //String nation = p.show("CHN");
        System.out.println(returnValue);

        System.out.println("*************如何调用静态方法*****************");

        // private static void showDesc()

        Method showDesc = clazz.getDeclaredMethod("showDesc");
        showDesc.setAccessible(true);
        //如果调用的运行时类中的方法没有返回值,则此invoke()返回null
//        Object returnVal = showDesc.invoke(null);
        Object returnVal = showDesc.invoke(Person.class);
        System.out.println(returnVal);//null

构造器:

 Class clazz = Person.class;

        //private Person(String name)
        /*
        1.获取指定的构造器
        getDeclaredConstructor():参数:指明构造器的参数列表
         */

        Constructor constructor = clazz.getDeclaredConstructor(String.class);

        //2.保证此构造器是可访问的
        constructor.setAccessible(true);

        //3.调用此构造器创建运行时类的对象
        Person per = (Person) constructor.newInstance("Tom");
        System.out.println(per);
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值